Reputation: 343
This really seems confusing but I want to create a Dictionary filled with different classes as the Values, then using letters as the keys. When I call a key in that dictionary, I need it to act as though I'm typing "new ClassInDictionary".
This is so I can create a text file with different symbols defining different blocks.
To help clear things up here's my current code:
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)
{
}
}
}
The variable blockIdentifier:
public static Dictionary<string, Block> blockIdentifier = new Dictionary<string, Block>();
And BlockDirt:
public class BlockDirt : Block
{
public int hi;
public BlockDirt()
: base("Dirt Block.png", 0, 0, true)
{
}
}
I simply need to call blockIdentifier["="] and get a new instance of the class BlockDirt(), how can I do this?
Upvotes: 1
Views: 6471
Reputation: 23300
I'd say the most logical way to do it would be to have Type
values in the dictionary
var blockIdentifier = new Dictionary<string, Type>();
blockIdentifier.Add("=", typeof(BlockDirt));
blockIdentifier.Add("-", typeof(BlockAir));
....
mapList[x,y] = blockIdentifier[symbol].GetConstructor(new Type[] { }).Invoke(null);
Upvotes: 0
Reputation: 3663
Do you want to create a new instance of the block each time or re-use a single instance of the block?
From the code it looks as if you want to create a new one each time. If so, one way is to make it a Dictionary<string, Func<Block>>
where all the blocks inherit from Block (or IBlock, which might be a bit better).
note
Assumes BlockAir : IBlock
and BlockDirt : IBlock
var blockLookup = new Dictionary<string, Func<IBlock>>();
blockLookup.Add("=", ()=> new BlockAir());
blockLookup.Add("-", ()=> new BlockDirt());
...
mapList[x,y] = blockLookup[symbol]();
...
or along those lines (I haven't got access to a dev. environment at the moment so apologies for any errors)
Upvotes: 8
Reputation: 17428
You could do this by storing ConstructorInfo
objects in your dictionary and then create objects via reflection. Maybe kind of hacky, but I think it will work.
Here is an example using StringBuilder constructor in a dictionary (you can throw this in LINQPad to see the output).
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();
So for your case, you want constructors for your different Block
objects:
var blockIdentifier = new Dictionary<string, ConstructorInfo>();
blockIdentifier["="] = typeof(BlockAir).GetConstructor(new Type[]{});
blockIdentifier["-"] = typeof(BlockDirt).GetConstructor(new Type[]{});
Upvotes: 1