2015-10-23 45 views
1

我想轉換字典,以便將值轉換爲由原始類型實現的接口;c#如何投用通用類型

首先:

public class DataRef<T> : IRef 
{ 
     public int ID; 
     public static Dictionary<int, T> LookUp = new Dictionary<int, T>(); 
} 

public class Terrain : IThing 
{ 
    ///IThing 
    public ImageRef DefaultImageRef { get { return defaultImageRef; } } 
    public string Name { get { return name; } } 
    public string name = "unamed Terrain"; 

    //Other Stuff 
    public TerrainType TerrainType = TerrainType.Floor; 
    public ImageRef defaultImageRef = new ImageRef(typeof(Terrain)); 
    public ImageRef alternateImageRef = new ImageRef(typeof(Terrain)); 
    public int imageRef2; 
} 

public interface IThing 
{ 
    ImageRef DefaultImageRef { get; } 
    string Name { get; } 
} 

這種表達不能編譯:

(Dictionary<int,IThing>)DataRef<Terrain>.LookUp 

錯誤:

Error 15 Cannot convert type 'System.Collections.Generic.Dictionary< int,MO1.Definitions.Terrain >' to 'System.Collections.Generic.Dictionary< int,MO1.Definitions.IThing >' C:\Projects\MO1RPG\VSsolution\Editor\Main.cs 28 72 Editor

我想投的字典,因爲我想用它作爲一個參數被轉換爲「Dictionary」有沒有辦法做到這一點?

回答

4

這是鑄造不可能的。您必須創建一個新的字典。

這是不直觀,在第一,因爲你可以這樣做:

Terrain dataRef = new Terrain(); 
IThing thing = (IThing)dataRef; 

但你不能做到這一點:

Dictionary<string, Terrain> dict = new Dictionary<string, Terrain>(); 
Dictionary<string, IThing> castDict = (Dictionary<string, IThing>)dict; 

這裏的區別是解釋道:https://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx

簡而言之,字典不是隻讀的,因此不能提供執行演員所需的某些保證。例如

Dictionary<string, Terrain> dict = new Dictionary<string, Terrain>(); 
Dictionary<string, IThing> castDict = (Dictionary<string, IThing>)dict; 
castDict.Add("Rob", new DifferentThing()); // DifferentThing implements IThing 

我們在這裏所做的是增加了一個DifferentThing到預計Terrain一本字典,這是一個很大的禁忌。爲什麼這是一個很大的禁忌?

因爲如果有人那麼做這個東西:Terrain terr = dict["Rob"]; 現在我們正在試圖存儲DifferentThingTerrain

你需要記住什麼是鑄造一個目的是(有例外,當然)創造一個新的對象,而是改變我們在外部看待它的方式。

爲了從Dictionary<string, Terrain>Dictionary<string, IThing>,你需要創建定義爲Dictionary<string, IThing>一個詞典和與原詞典填充它。

請參閱BrianMains的答案

1

您可以嘗試使用Cast Linq方法,但您可能需要改爲使用通用的ToDictionary(k => k.Key, v => (IThing)v.Value);選項。