Же код для разбора инт, флоат, десятичное?


У меня есть метод для разбора строки. Он может быть использован для анализа поплавок использованием определенной культуры , а затем получить новую строку с определенногокультуре. То же самое относится к ИНЦ, парный и десятичные.

Код, который я написал довольно однообразные для каждого из различных методов анализа, что делает его трудно поддерживать (тем более, что я как раз собирался сделать метод намного сложнее).

Можно ли сделать этот код меньше повторов?

if (mapping.ParseDecimal)
{
    decimal i;
    if (decimal.TryParse(value, numberStyle, inCulture, out i))
    {
        return i.ToString(outCulture);
    }
    else
    {
        if (logger.IsDebugEnabled)
            logger.DebugFormat("Could not parse value \"{0\" to a decimal using the culture \"{1}\".", value, inCulture);
    }
}
else if (mapping.ParseDouble)
{
    double i;
    if (double.TryParse(value, numberStyle, inCulture, out i))
    {
        return i.ToString(outCulture);
    }
    else
    {
        if (logger.IsDebugEnabled)
            logger.DebugFormat("Could not parse value \"{0\" to a double using the culture \"{1}\".", value, inCulture);
    }
}
else if (mapping.ParseFloat)
{
    float i;
    if (float.TryParse(value, numberStyle, inCulture, out i))
    {
        return i.ToString(outCulture);
    }
    else
    {
        if (logger.IsDebugEnabled)
            logger.DebugFormat("Could not parse value \"{0\" to a float using the culture \"{1}\".", value, inCulture);
    }
}
else if (mapping.ParseInt)
{
    int i;
    if (int.TryParse(value, numberStyle, inCulture, out i))
    {
        return i.ToString(outCulture);
    }
    else
    {
        if (logger.IsDebugEnabled)
            logger.DebugFormat("Could not parse value \"{0\" to a int using the culture \"{1}\".", value, inCulture);
    }
}


6754
8
задан 28 июля 2011 в 09:07 Источник Поделиться
Комментарии
2 ответа

Если повторение-это ваша главная задача, вы могли бы попробовать делать что-то вроде этого:

public delegate string ParserMethod(string value, NumberStyles numberStyle, CultureInfo inCulture, CultureInfo outCulture);

public static class NumericParser
{
public static readonly ParserMethod ParseInt = Create<int>(int.TryParse);
public static readonly ParserMethod ParseFloat = Create<float>(float.TryParse);
public static readonly ParserMethod ParseDouble = Create<double>(double.TryParse);
public static readonly ParserMethod ParseDecimal = Create<decimal>(decimal.TryParse);

public static Logger Logger { get; set; }

delegate bool TryParseMethod<T>(string s, NumberStyles style, IFormatProvider provider, out T result);
static ParserMethod Create<T>(TryParseMethod<T> tryParse) where T : IFormattable
{
return (value, numberStyle, inCulture, outCulture) =>
{
T result;
if (tryParse(value, numberStyle, inCulture, out result))
{
return result.ToString(null, outCulture);
}
else
{
if (Logger != null && Logger.IsDebugEnabled)
Logger.DebugFormat("Could not parse value \"{0}\" to a {1} using the culture \"{2}\".", value, typeof(T).Name, inCulture);
return "";
}
};
}
}

Таким образом, вы только должны пройти по соответствующей ParserMethod , который вы хотите использовать. В вашем случае, вы могли бы сопоставить различные сопоставления значений соответствующих ParserMethod. И назвать его при необходимости.

14
ответ дан 28 июля 2011 в 10:07 Источник Поделиться

У меня есть метод, который делает что-то подобное в том, что он принимает строку и преобразует его в данный примитивный тип. Он использует дженерики, так что там меньше кода.

    public static T ReadConfigItem<T>(string strValue, IFormatProvider formatProvider) where T : struct
{
T result;

if (string.IsNullOrEmpty(strValue))
{
result = (T)(Convert.ChangeType(false, typeof(T), formatProvider));
}
else
{
result = (T)(Convert.ChangeType(strValue, typeof(T), formatProvider));
}

return result;
}

Затем он может быть использован такой:

    System.Globalization.CultureInfo c = new System.Globalization.CultureInfo("fr-FR");
Console.WriteLine(ReadConfigItem<double>("90,99", c));
Console.WriteLine(ReadConfigItem<double>("9", c));
Console.WriteLine(ReadConfigItem<int>("6", c));
Console.WriteLine(ReadConfigItem<double>(null, c));
Console.WriteLine(ReadConfigItem<int>(null, c));
Console.WriteLine(ReadConfigItem<bool>("true", c));
Console.WriteLine(ReadConfigItem<bool>("True", c));
Console.WriteLine(ReadConfigItem<bool>(null, c));

Я в Великобритании и на выходе я получаю:

90.99
9
6
0
0
True
True
False

Если вы хотели вы могли бы изменить это метод расширения класса String.

Пример расширения класса:

public static class ConvertExtensions
{
public static T ConvertTo<T>(this string strValue, IFormatProvider formatProvider) where T : struct
{
T result;

if (string.IsNullOrEmpty(strValue))
{
result = (T)(Convert.ChangeType(false, typeof(T), formatProvider));
}
else
{
result = (T)(Convert.ChangeType(strValue, typeof(T), formatProvider));
}

return result;
}
}

Использование:

CultureInfo c = new CultureInfo("fr-FR");    
Console.WriteLine("".ConvertTo<double>(c));
Console.WriteLine("True".ConvertTo<bool>(c));
Console.WriteLine("true".ConvertTo<bool>(c));
Console.WriteLine("".ConvertTo<bool>(c));
Console.WriteLine("".ConvertTo<decimal>(c));

4
ответ дан 28 июля 2011 в 10:07 Источник Поделиться