2012-08-08 242 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中的對象之間不存在任何轉換,這將引發異常