一般的TryParse Nullable类型

时间:2013-05-31 07:00:52

标签: c# .net parsing generics type-conversion

我为以下TryParse类型编写了重载的静态Nullable方法:int?short?long?double?,{{ 1}},DateTime?decimal?float?bool?byte?。以下是一些实现:

char?

除了使用不同类型之外,每种方法的逻辑都相同。是否不可能使用泛型,以便我不需要有如此多的冗余代码?签名看起来像这样:

protected static bool TryParse(string input, out int? value)
{
    int outValue;
    bool result = Int32.TryParse(input, out outValue);
    value = outValue;
    return result;
}

protected static bool TryParse(string input, out short? value)
{
    short outValue;
    bool result = Int16.TryParse(input, out outValue);
    value = outValue;
    return result;
}

protected static bool TryParse(string input, out long? value)
{
    long outValue;
    bool result = Int64.TryParse(input, out outValue);
    value = outValue;
    return result;
}

由于

3 个答案:

答案 0 :(得分:9)

  

是否不可能使用泛型,以便我不需要那么多的冗余代码?

你可以用反射来做,但那会比较慢。否则,你可以创建一个从类型到“用于该类型的方法”的映射,但它会非常难看。除了其他任何东西,它永远不会是真正的泛型 - 它只适用于提供正确签名的TryParse方法的类型,这在编译时是无法知道的。

顺便说一句,我个人会考虑改变签名和行为。目前即使value的类型可以为空,即使返回false,它也不会在方法结尾处具有空值。为什么不将返回值作为解析操作的结果,在失败时返回null

protected static long? TryParseInt64(string input)
{
    long outValue;
    return Int64.TryParse(input, out outValue) ? (long?) outValue : null;
}

答案 1 :(得分:6)

您可以使用以下通用扩展方法

public static Nullable<TSource> TryParse<TSource>(this string input) where TSource : struct
{
    try
    {
        var result = Convert.ChangeType(input, typeof(TSource));
        if (result != null)
        {
            return (TSource)result;
        }
        return null;
    }
    catch (Exception)
    {
        return null;
    }
}

以下调用将返回可为空的解析类型。

string s = "510";
int? test = s.TryParse<int>();
//TryParse Returns 510 and stored in variable test.

string s = "TestInt";
int? test = s.TryParse<int>();
//TryParse Returns null and stored in variable test.

答案 2 :(得分:4)

顺便说一下,你可以重构你的代码:

public static bool TryParse(string input, out int? value)
{
    return TryParse(input, Int32.TryParse, out value);
}

protected static bool TryParse(string input, out short? value)
{
    return TryParse(input, Int16.TryParse, out value);
}

protected static bool TryParse(string input, out long? value)
{
    return TryParse(input, Int64.TryParse, out value);
}

private static bool TryParse<T>(string input, TryParseFunc<T> tryParse, out T? value)
    where T : struct
{
    T outValue;
    bool result = tryParse(input, out outValue);
    value = outValue;
    return result;
}

private delegate bool TryParseFunc<T>(string input, out T value);