Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# reflection and instantiation - is there a way to do Activator.CreateInstance(myType){ X = x }?

I'm not sure of the terminology for this kind of code, but I want to know if it's possible to instantiate variables after the parentheses, but whilst using reflection.

I have a map which gets loaded from an XML file. This is a collection of (int X, int Y, string S) where the X,Y is the position of some terrain, and S is a string representing the type of the terrain. I have a dictionary to pass between the strings and the relevant types; for example one key-value pair might be "Tree", typeof(Tree).

When using reflection, although I know it's possible to instantiate with parameters, the only way I'm comfortable is just by using Activator.CreateInstance(Type t), i.e. with an empty constructor.

When I had the maps hard coded, I would originally instantiate like this (within some i,j for loop):

case: "Tree"
 world.Add( new Tree(i,j) );

Whilst starting to think about reflection and my save file, I changed this to:

world.Add( new Tree() { X = i, Y = j }

However, I realised that this won't work with reflection, so I am having to do the following (Tree inherits from Terrain, and the dictionary just converts the XML save data string to a type):

Type type = dictionary[dataItem.typeAsString];
Terrain t = (Terrain)Activator.CreateInstance(type);
t.X = i;
t.Y = j;
world.Add(t);

I would prefer to do this using something like

Type type = dictionary[dataItem.typeAsString];
world.Add((Terrain)Activator.CreateInstance(type) { X = i, Y = j }

Is there any shortcut like this? I guess if not I could edit world.Add to take an X and Y and cast to Terrain in there to access those variables, but I am still curious as to a) what this {var1 = X, var2 = Y} programming is called, and b) whether something similar exists when using reflection.

like image 208
Haighstrom Avatar asked Jan 16 '13 16:01

Haighstrom


1 Answers

This syntax is called Object Initializer syntax and is just syntactic sugar for setting the properties.

The code var result = new MyType { X = x } will be compiled to this:

MyType __tmp = new MyType();
__tmp.X = x;
MyType result = __tmp;

You will have to do that yourself using PropertyInfo.SetValue if you know the instantiated type only at runtime or use the normal property setters if the type is known at compile time.

like image 54
Daniel Hilgarth Avatar answered Sep 22 '22 05:09

Daniel Hilgarth