Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return type of generic method

I have a generic method which is to return an object of the generic type. Some code:

public static T Foo<T>(string value)
{
    if (typeof(T) == typeof(String))
        return value;

    if (typeof(T) == typeof(int))
        return Int32.Parse(value);

    // Do more stuff
}

I can see that the compiler might complain about this ("Cannot convert type 'String' to 'T'"), even if the code shouldn't cause any logical errors runtime. Is there any way to achieve what I'm looking for? Casting doesn't help...

like image 540
Christian Rygg Avatar asked Feb 21 '11 12:02

Christian Rygg


1 Answers

Well, you can do this:

public static T Foo<T>(string value)
{
    if (typeof(T) == typeof(String))
        return (T) (object) value;

    if (typeof(T) == typeof(int))
        return (T) (object) Int32.Parse(value);

    ...
}

That will involve boxing for value types, but it will work.

Are you sure this is best done as a single method though, rather than (say) a generic interface which can be implemented by different converters?

Alternatively, you might want a Dictionary<Type, Delegate> like this:

Dictionary<Type, Delegate> converters = new Dictionary<Type, Delegate>
{
    { typeof(string), new Func<string, string>(x => x) }
    { typeof(int), new Func<string, int>(x => int.Parse(x)) },
}

then you'd use it like this:

public static T Foo<T>(string value)
{
    Delegate converter;
    if (converters.TryGetValue(typeof(T), out converter))
    {
        // We know the delegate will really be of the right type
        var strongConverter = (Func<string, T>) converter;
        return strongConverter(value);
    }
    // Oops... no such converter. Throw exception or whatever
}
like image 159
Jon Skeet Avatar answered Nov 16 '22 01:11

Jon Skeet