Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Method Return Type as Type parameter

Tags:

c#

.net

generics

I have an extension method that is working ok to cast string values into various types, which looks something like this:

public static T ToType<T> (this string value, T property)
    {
        object parsedValue = default(T);
        Type type = property.GetType();

        try
        {
            parsedValue = Convert.ChangeType(value, type);
        }
        catch (ArgumentException e)
        {
            parsedValue = null;
        }

        return (T)parsedValue;
    }

I'm unhappy about the way this looks when calling the method, however:

myObject.someProperty = stringData.ToType(myObject.someProperty);

Specifying the property just to obtain the property's type seems redundant. I would rather use a signature like this:

public static T ToType<T> (this string value, Type type) { ... }

and have T end up to be the Type of type. This would make calls much cleaner:

myObject.someProperty = stringData.ToType(typeof(decimal));

When I try to call this way, however, the editor complains that the return type of the extension method can't be infered from usage. Can I link T to the Type argument?

What am I missing?

Thanks

like image 610
ZuluAlphaCharlie Avatar asked Jul 23 '13 17:07

ZuluAlphaCharlie


2 Answers

Is this what you are looking for? I've added an extra catch for cases where the cast isn't valid also

Decimal i = stringName.ToType<Decimal>();

public static T ToType<T>(this string value)
{
     object parsedValue = default(T);
     try
     {
         parsedValue = Convert.ChangeType(value, typeof(T));
     }
     catch (InvalidCastException)
     {
         parsedValue = null;
     }
     catch (ArgumentException)
     {
         parsedValue = null;
     }
     return (T)parsedValue;
} 

Edit

a shortcut approach to fix Anton's comment

if (typeof(T).IsValueType)
   return default(T);
like image 128
Sayse Avatar answered Nov 15 '22 16:11

Sayse


Why use property at all? Just change how you're setting your type variable to the type of your generic.

    public static T ToType<T>(this string value)
    {
        object parsedValue = default(T);
        Type type = typeof(T);

        try
        {
            parsedValue = Convert.ChangeType(value, type);
        }
        catch (ArgumentException e)
        {
            parsedValue = null;
        }

        return (T) parsedValue;
    }

Usage:

myObject.someProperty = stringData.ToType<decimal>()
like image 32
McAden Avatar answered Nov 15 '22 17:11

McAden