I have two objects that have exactly the same properties. Here's an example:
public class Field<T>
{
public T Value {get;set;}
// more things
}
public class MainObject
{
public string MyStr {get;set;}
public int? MyInt {get;set;}
public bool? MyBool {get;set;}
}
public class MainObjectField
{
public Field<string> MyStr {get;set;}
public Field<int?> MyInt {get;set;}
public Field<bool?> MyBool {get;set;}
}
I have a task to create an instance of MainObjectField
based on xpath instructions that I get from an external source.
I need to fetch the Value
from the MainObject
's instance as a part of the task.
Since I don't know about the type of the current property in compile type, I'm using a dynamic variable.
Here's a short example (this is NOT how the code looks like in real life - this example if to simplify the post):
MainObject obj = new MainObject
{
MyBool = true,
MyInt = 12,
MyStr = "Example"
};
MainObjectField fieldObj = new MainObjectField();
var myBool = obj.GetType().GetProperty("MyBool").GetValue(obj);
var myInt = obj.GetType().GetProperty("MyInt").GetValue(obj);
var myStr = obj.GetType().GetProperty("MyStr").GetValue(obj);
dynamic fieldBool = Activator.CreateInstance(typeof(Field<bool?>));
dynamic fieldInt = Activator.CreateInstance(typeof(Field<int?>));
dynamic fieldString = Activator.CreateInstance(typeof(Field<string>));
fieldBool.Value = myBool; // exception
fieldInt.Value = myInt; // exception
fieldString.Value = myStr; // exception
fieldObj.MyBool = fieldBool;
fieldObj.MyInt = fieldInt;
fieldObj.MyStr = fieldString;
Now I'm getting this exception:
Cannot implicitly convert type 'object' to 'bool?'. An explicit conversion exists (are you missing a cast?)
I understand why I'm getting the exception and I'm trying to find a workaround.
I know that the currentField.Value
and the val
value are suppose to be the same type.
My problem is that using reflection (GetValue
returns an object
) automatically casts\boxes the value into an object
and ruins my plans.
I can't cast to the "correct" value since I know the types only in runtime.
How can I work this around?
The problem is that the binder will use the static type of the value you're trying to assign to the property - whereas you want to do this dynamically. All you need to do is change the variables to be of type dynamic
and it works:
dynamic myBool = obj.GetType().GetProperty("MyBool").GetValue(obj);
dynamic myInt = obj.GetType().GetProperty("MyInt").GetValue(obj);
dynamic myStr = obj.GetType().GetProperty("MyStr").GetValue(obj);
Basically, dynamic typing will work dynamically with any expressions with a compile-time type of dynamic
, but will use the compile-time type of any other expressions when performing that binding.
See more on this question at Stackoverflow