2012-08-08 231 views
6

我正在编写一个方法来执行智能类型转换 - 如果类型参数碰巧是字符串,则使用ToString();否则如果转换不转换则返回null工作。基本上可以从v中获取尽可能多的信息,而不会引发异常。将字符串转换为字符串的泛型类型

我检查T的确是一个string之前,我尝试中投,但编译器仍然不是一个球迷:

Cannot convert type 'string' to 'T' 

这是我的方法:

public T? Convert<T>(object v) 
{ 
    if (typeof(T) == typeof(string)) { 
    return (T)v.ToString(); // Cannot convert type 'string' to 'T' 
    } else try { 
     return (T)v; 
    } catch (InvalidCastException) { 
    return null; 
    } 
} 

也让我知道如果这是某种不可饶恕的罪行。我用它来处理可能有混合类型的一些数据结构。

+0

还有其他问题。当'T'没有限制时,你的方法不能有'T?'返回类型。例如,没有什么叫'string?',因为string是一个引用类型。 – 2012-08-08 15:05:52

回答

25

强制转换为泛型类型时,你基本上需要通过object去:

return (T)(object) v.ToString() 

return (T)(object) v; 

我会用is但不是赶上InvalidCastException

查看Eric Lippert's recent blog post了解为什么这是必要的更多细节。

特别是:

因为编译器知道这种转换可能可能成功的唯一途径是,如果U是布尔,但U可以是任何东西!编译器假定大部分时间U不会与bool一起构造,因此这段代码几乎肯定是一个错误,编译器正在引起您的注意。

(替代TUstringbool ...)

+1

在这里不会是更好的选择吗? – 2012-08-08 14:07:58

+1

@SteveCzetty:我们不知道'T'是一个可以为空的类型,所以'as'不起作用(IIRC)。 – 2012-08-08 14:08:45

+0

好点。虽然我不认为'是'也会起作用,除非'T'被限制为'class'。 (IIRC也) – 2012-08-08 14:10:50

2

你需要转换你的字符串作为object为您的返回类型是通用的,即

return (T)(object)v.ToString(); 
+1

这不是拳击。没有涉及的价值类型。 – 2012-08-08 14:08:14

+0

@JonSkeet耶使用了错误的词!想要说演员... – James 2012-08-08 14:09:29

0

尝试转换到object转换为T

return (T)(object)v; 
0
using System.ComponentModel; 

前...

public T Convert<T>(object v) { 
    return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(v); 
} 

警告,如果在T与包含在v中的对象之间不存在任何转换,这将引发异常