2010-10-29 123 views
11

爲什麼下面編譯?仿製藥和鑄造

public IList<T> Deserialize<T>(string xml) 
{    
    if (typeof(T) == typeof(bool)) 
     return (IList<T>)DeserializeBools(xml); 

    return null; 
} 

private static IList<bool> DeserializeBool(string xml) { ... do stuff ... } 

但這並不

public MyClass<T> GetFromDb<T>(string id) 
{ 
    if (typeof(T) == typeof(bool)) 
     return (MyClass<T>)GetBoolValue(id); <-- compiler error here 

    return null; 
} 

private static MyClass<bool> GetBoolValue(string id) { ... do stuff ... } 
+5

什麼是編譯錯誤... – 2010-10-29 10:47:40

+0

錯誤說的是什麼? – 2010-10-29 10:49:23

+0

無法投射'MyClass '類型的表達式來鍵入'MyClass ' – Magpie 2010-10-29 10:49:55

回答

20

更換

return (MyClass<T>)

會發生什麼原因的接口工作是任何對象可能實現IList<T>(除非它是已知的實例一個密封的類型,不實現它,我猜) - 所以總是有可能引用類型轉換爲接口。

在後一種情況下,編譯器也不願意這樣做,因爲它並沒有真正知道T是布爾,儘管以前if語句,所以它不知道MyClass<T>MyClass<bool>之間嘗試什麼轉換。不幸的是,對泛型的有效轉換是相當有限的。

你可以很容易解決這個問題:

return (MyClass<T>)(object) GetBoolValue(id); 

這是醜陋的,但它應該工作...至少在這種情況下,它不會導致任何拳擊。

+0

它的確如此,謝謝 – Magpie 2010-10-29 10:56:04

0

C#4.0允許協變和逆變的參數接口和委託類型的聲明。

+0

這不是試圖使用通用方差,而是通用方差不適用於值類型類型參數。 – 2010-10-29 10:52:48

0

,如果你有

return (MyClass<bool>) 
+1

然後它將無法從'MyClass '轉換爲返回類型所需的'MyClass '。 – 2010-10-29 10:52:08