tags:

views:

77

answers:

1

I want to have a generic function for a few types such as long, TimeSpan and DateTime.

public static T Parse<T>(string text)
{
    T store;

    if(typeof(T) == typeof(TimeSpan)
        store = (T)((object) new TimeSpan(0, 1, 0));
    else
    {
        T.tryParse(text, out store);
    }
    return store;
}

Is there a better way than the double T/object cast?

The t.tryParse does not compile, how can I accomplish something similar?

+6  A: 

It feels to me like it would be better to have an overloaded method in this case. There's nothing really generic about calling TryParse - Int32.TryParse is an entirely different method from Int64.TryParse etc. That will get you away from the double cast, too (which I agree is ugly, but unfortunately hard to avoid). It also means you'd be specifying which types you can genuinely support.

One alternative is to use a Dictionary<Type, Func<string, object>>:

// Add some error checking, obviously :)
Func<string, object> parser = parsers[typeof(T)];
return (T) parser(form.Text);

then set up the dictionary with something like:

static readonly Dictionary<Type, Func<string, object>> parsers = 
    new Dictionary<Type, Func<string, object>>()
{
    { typeof(int), x => int.Parse(x) },
    { typeof(TimeSpan) x => new TimeSpan(0, 1, 0) },
    ...
}

If you want to use TryParse instead of Parse, you'll need to create your own delegate type due to the use of out parameters (which aren't supported in Func/Action). Life becomes a little harder at that point.

As an aside, why are you using an out parameter instead of a return value?

Jon Skeet
The out in the Parse<T> function was to match the out in the TryParse call. My question only had an except of the real code that does return a bool that represent the outcome of TryParse.I will shortly look into the answer, thanks.
phq
Removed the out in response to your question to keep my question focused.
phq