通用方法返回类型作为类型参数

时间:2013-07-23 17:49:00

标签: c# .net generics

我有一个扩展方法,可以将字符串值转换为各种类型,如下所示:

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

我对调用该方法时的外观方式不满意,但是:

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

指定属性只是为了获取属性的类型似乎是多余的。我宁愿使用这样的签名:

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

并且T最终为类型类型。这会使通话变得更加清洁:

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

但是,当我尝试以这种方式调用时,编辑器会抱怨扩展方法的返回类型不能用于使用。我可以将T链接到Type参数吗?

我错过了什么?

由于

3 个答案:

答案 0 :(得分:16)

这是你在找什么?我为演员阵容无效的情况添加了额外的捕捉

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

修改

修复Anton评论的捷径方法

if (typeof(T).IsValueType)
   return default(T);

答案 1 :(得分:2)

为什么要使用财产?只需更改将类型变量设置为通用类型的方式。

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

用法:

myObject.someProperty = stringData.ToType<decimal>()

答案 2 :(得分:0)

我正在使用它进行通用转换:

    public bool ConvertTo<T>(object from, out T to) {
        to = default(T);
        if (from is T) { to = (T)from; return true; }                                           
        Type t = typeof(T);
        //TypeConverter converter = p.converter == null ? TypeDescriptor.GetConverter(t) : p.converter;
        TypeConverter converter = TypeDescriptor.GetConverter(t);
        if ((converter != null) && (converter.CanConvertTo(t))) {
            try { to = (T)converter.ConvertTo(null, culture, from, t); return true; }
            catch { }
        }
        try { to = (T)Convert.ChangeType(from, t, culture); return true; }
        catch { }
        return false;                                                                                       
    }

    public bool ConvertTo(object from, out object to, Type type) {
        to = null;
        if (from.GetType() == type) { to = from; return true; }     
        TypeConverter converter = TypeDescriptor.GetConverter(type);
        if ((converter != null) && (converter.CanConvertTo(type))) {
            try { to = converter.ConvertTo(null, culture, from, type); return true; }
            catch { }
        }
        try { to = Convert.ChangeType(from, type, culture); return true; }
        catch { }
        return false;                                           
    }

在调用Convert.ChangeType之前,会检查给定变量是否有TypeConverter

这样称呼:

int i = 123;
string s;
if (ConvertTo<string>(i, out s) {
    // use s
}