2009-06-30 44 views
0

我:IDictionary的,字典

IDictionary<string, IDictionary<string, IList<long>>> OldDic1; 

(只是爲了演示,它被實例化並具有價值 - 別的地方)

我爲什麼能做到這一點?

Dictionary<string, IDictionary<string, IList<long>>> dic1 = 
    OldDic1 as Dictionary<string, IDictionary<string, IList<long>>>; 

基本上dic1在執行這行後有所有OldDic1的值;作品。

然而,當我這樣做:

Dictionary<string, Dictionary<string, List<long>>> dic1 = 
    OldDic1 as Dictionary<string, Dictionary<string, List<long>>>; 

我得到空,這是一樣的,除了它的鑄造不會崩潰,而是返回null。所以問題是爲什麼我不能將它從接口轉換爲類型?有沒有解決方案,除了改變它的存儲方式?

+0

鑄造有點混亂。當進行這種類型的轉換(或使用「as」)時,基本上所有您正在做的是檢查對象是否實際上是存儲器中的指定類型。您不是創建一個具有該類型的新對象,而只是檢查。如果還不清楚,請閱讀以下文章:http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx – 2009-06-30 16:09:13

+0

謝謝,優秀的文章。 – ra170 2009-06-30 16:45:13

回答

2

您只能重新投射最外層的界面/類名稱,而不是通用參數。第二次強制轉換不起作用的原因與無法從一個陣列類型轉換爲另一個陣列類型的原因相同,即使您可以投射「包含」對象。原因如下:

List<object> objects; 
List<string> strings; 

objects = strings as List<object>; 
// Uh oh, that's not a string! 
objects.Add(42); 

objects = new List<object> { "The", "answer", "is", 42 }; 
// Uh oh, now strings contains an integer? 
strings = objects as List<string>; 

在第二種情況下會發生同樣的情況。您可以添加某種IDictionaryOldDic1這實際上不是Dictionary,然後dic1會炸燬。它會有一個非Dictionary值。 Ruh roh!

所以,當你有容器,你可以只要改變從IList<X>List<X>和背部爲X是每個相同

0

該行爲與C#中的as keyword有關。字典與IDictionary不同。

如果您正在以另一種方式進行轉換,您可能可以在下一版本的.NET中工作,該版本已增加對covariance and contravariance的支持。

您可能想要確定的解決方案爲什麼需要轉換爲具體的Dictionary/List,如果需要,則更改類型的存儲。

+0

我必須將其轉換爲具體類型的原因是DataContractJsonSerializer,它需要類型。當對象是conrete類型時,我可以說dic1.GetType(),但是如果我在接口上這樣做,DataContractJsonSeralizer .writeobject會拋出異常 – ra170 2009-06-30 16:26:16