Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 泛型方法返回类型作为类型参数_C#_.net_Generics - Fatal编程技术网

C# 泛型方法返回类型作为类型参数

C# 泛型方法返回类型作为类型参数,c#,.net,generics,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(v

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

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;
    }
public static T ToType<T> (this string value, Type type) { ... }
仅为获取属性的类型而指定属性似乎是多余的。我宁愿使用这样的签名:

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;
    }
public static T ToType<T> (this string value, Type type) { ... }
然而,当我尝试以这种方式调用时,编辑器抱怨无法从用法推断扩展方法的返回类型。我可以将T链接到类型参数吗

我错过了什么


谢谢这就是你要找的吗?我已经为演员阵容无效的情况添加了一个额外的捕获

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

为什么要使用财产呢?只需将类型变量设置为泛型变量的类型

    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;
    }
public static T ToType(此字符串值)
{
object parsedValue=默认值(T);
类型=类型(T);
尝试
{
parsedValue=Convert.ChangeType(值,类型);
}
捕获(e)
{
parsedValue=null;
}
返回(T)parsedValue;
}
用法:

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

我将此用于一般转换:

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

我可以将T链接到类型参数吗?-不是直接的。您混淆了编译时和运行时。在编译代码时,C#编译器必须在处理对
ToType
的调用时决定
T
是什么。每次调用
ToType
时,OTOH
type
都假定一个可能不同的值。---------------------------------------------------------------\-您可以使用动态编译的一种风格,但这是一种高级技术,最好保留在少数真正需要的情况下。感谢大家的回答和输入。“专门指定类型参数”正是他在代码的第一行中所做的。这是一种使用尖括号调用语法的特殊方法,尽管它应该适用于您的情况。抱歉,Sayse。它起作用了。我把这句话漏掉了call@Sayse顺便说一句,如果
T
是值类型,则无法将
null
转换为
T
。通常的解决方法是有两个版本的这个方法,一个用于返回a
T?
的值类型,另一个用于返回
T
@AntonTykhyy的引用类型-你是对的,我没有用值类型测试过这一点,尽管我不相信OP会使用它们,感谢预期的类型中有一个是decimal,我已经更新了异常路径,将parsedValue恢复为默认(T)Aha!我忘了在调用中指定T。。。ToType()!这很有效。谢谢
    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;                                           
    }
int i = 123;
string s;
if (ConvertTo<string>(i, out s) {
    // use s
}