TryParse Nullable types generically [duplicate]

2019-01-26 13:13发布

This question already has an answer here:

I have written overloaded static TryParse methods for the following Nullable types: int?, short?, long?, double?, DateTime?, decimal?, float?, bool?, byte? and char?. Below is some of the implementation:

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;
}

The logic is the same in every method except that they use different types. Would it not be possible to use generics so that I don't need to have so much redundant code? The signature would look like this:

bool TryParse<T>(string input, out T value);

Thanks

3条回答
劫难
2楼-- · 2019-01-26 13:43

Would it not be possible to use generics so that I don't need to have so much redundant code?

You could do it with reflection, but that would be relatively slow. Otherwise, you could create a map from type to "method to use for that type" but it would be pretty ugly. Aside from anything else, it would never be truly generic - it would only work for types that provided a TryParse method of the right signature, which couldn't be known at compile-time.

I would personally consider changing the signature and behaviour, by the way. Currently even though the type of value is nullable, it will never have the null value at the end of the method, even if you return false. Why not make the return value the result of the parsing operation, returning null on failure?

protected static long? TryParseInt64(string input)
{
    long outValue;
    return Int64.TryParse(input, out outValue) ? (long?) outValue : null;
}
查看更多
做个烂人
3楼-- · 2019-01-26 13:46

As an aside, you could refactor your code:

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);
查看更多
Deceive 欺骗
4楼-- · 2019-01-26 13:47

You could use the following generic extension method,

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;
    }
}

The following call will return the nullable parsed type.

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.
查看更多
登录 后发表回答