2013-02-08 83 views
1

這看起來確實令人困惑,但我想創建一個填充不同類作爲值的字典,然後使用字母作爲鍵。當我在該字典中調用一個鍵時,我需要它充當我鍵入「新的ClassInDictionary」的行爲。C#在字典中添加一個類並創建一個新的實例

這樣我就可以用不同的塊定義不同的符號來創建一個文本文件。

要在這裏幫助你弄明白是我當前的代碼:

blockIdentifier.Add("=", new BlockAir()); // Define which class corresponds to which letter 
blockIdentifier.Add("-", new BlockDirt()); 

for (int mapX = 0; mapX < mapWidth; mapX++) 
{ 
    for (int mapY = 0; mapY < mapHeight; mapY++) 
    { 
     try 
     { 
      Block block = blockIdentifier[mapSplit[mapY].Substring(mapX, 1)]; // Simply find which letter to use, let's pretend it's: "=" 
      // The line above should be creating a new instance of the class BlockAir             
      block.blockX = mapX * 45; 
      block.blockY = mapY * 45; 

      mapList[mapY, mapX] = block; 
     } 
     catch (Exception) 
     { 
     } 
    } 
} 

變量blockIdentifier:

public static Dictionary<string, Block> blockIdentifier = new Dictionary<string, Block>(); 

而且BlockDirt:

public class BlockDirt : Block 
{ 
    public int hi; 

    public BlockDirt() 
     : base("Dirt Block.png", 0, 0, true) 
    { 
    } 
} 

我只需要調用blockIdentifier [」 =「]並獲得類BlockDirt()的新實例,我該如何做到這一點?

+1

而你的問題是? – Pete 2013-02-08 14:12:27

+0

你最初如何儲存課程? – 2013-02-08 14:13:28

+0

對不起,我真的忘了主要部分。我只需要調用blockIdentifier [「=」]並獲得BlockDirt類的新實例() – 2013-02-08 14:16:11

回答

1

您可以通過在字典中存儲ConstructorInfo對象來完成此操作,然後通過反射來創建對象。也許有點哈克,但我認爲它會起作用。

下面是一個在字典中使用StringBuilder構造函數的示例(您可以將它放在LINQPad中以查看輸出)。

var creator = typeof(StringBuilder).GetConstructor(new Type[]{}); 
var dict = new Dictionary<string, ConstructorInfo>(); 

dict["a"] = creator; 

StringBuilder b = (StringBuilder)dict["a"].Invoke(new object[]{}); 
b.AppendLine("Hello World"); 
b.ToString().Dump(); 

所以對於你的情況,你想構造爲不同Block對象:

var blockIdentifier = new Dictionary<string, ConstructorInfo>(); 
blockIdentifier["="] = typeof(BlockAir).GetConstructor(new Type[]{}); 
blockIdentifier["-"] = typeof(BlockDirt).GetConstructor(new Type[]{}); 
+0

Ehhh,這對我來說並不是最佳的。你會推薦我使用哪些其他選項?我真正需要做的是用不同的字符串定義不同類型的塊。這樣我就可以讀取保存文本的文本文件,例如; = - = - =,這將轉化爲污垢,空氣,污垢,空氣,污垢。 – 2013-02-08 14:21:58

7

你要創建的每個時間或再使用的單個實例塊的新實例塊?

從代碼看來,您每次都想創建一個新代碼。如果是這樣,一種方法是使其成爲Dictionary<string, Func<Block>>,其中所有塊從塊(或IBlock,可能會更好一點)繼承。


(目前我還沒有獲得一個開發,環境,所以道歉對任何錯誤)假設BlockAir : IBlockBlockDirt : IBlock

var blockLookup = new Dictionary<string, Func<IBlock>>(); 
blockLookup.Add("=",()=> new BlockAir()); 
blockLookup.Add("-",()=> new BlockDirt()); 

... 

mapList[x,y] = blockLookup[symbol](); 

... 

或沿着這些線路的

+1

+1 - 真棒 - 我在想「構造函數」,但是爲創建存儲一個lambda表達式是一個更好的方法。好決定。 – pstrjds 2013-02-08 14:21:49

+0

在一個!完美,非常感謝朋友! – 2013-02-08 14:26:53

+0

本質上你已經創建了一個工廠字典。它很古怪。我喜歡。 – BTownTKD 2013-02-08 14:39:23

0

我'd說最合乎邏輯的方法是在字典中有Type

var blockIdentifier = new Dictionary<string, Type>(); 
blockIdentifier.Add("=", typeof(BlockDirt)); 
blockIdentifier.Add("-", typeof(BlockAir)); 

.... 

mapList[x,y] = blockIdentifier[symbol].GetConstructor(new Type[] { }).Invoke(null);