Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TryParse Nullable types generically [duplicate]

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

like image 813
Dave New Avatar asked May 31 '13 07:05

Dave New


2 Answers

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;
}
like image 195
Jon Skeet Avatar answered Oct 01 '22 14:10

Jon Skeet


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.
like image 23
petchirajan Avatar answered Oct 01 '22 16:10

petchirajan