使用反射为动态类型赋值并绕过GetValue返回的对象强制转换框

时间:2015-09-01 16:23:57

标签: c# dynamic reflection casting

我有两个具有完全相同属性的对象。这是一个例子:

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;}
}

我有一项任务是根据我从外部来源获得的xpath指令创建MainObjectField的实例。
我需要从Value的实例中获取MainObject作为任务的一部分。

由于我不知道编译类型中当前属性的类型,我使用的是动态变量。

这是一个简短的例子(这是代码在现实生活中的样子 - 这个例子是为了简化帖子):

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;

现在我得到了这个例外:

  

无法将类型'object'隐式转换为'bool?'。一个明确的   存在转换(你错过了演员吗?)

我明白为什么我得到了例外,我正在努力寻找解决方法。

我知道currentField.Valueval值假设属于同一类型。

我的问题是使用反射(GetValue会返回object)会自动将值转换为{object,并破坏我的计划。 我无法转换为“正确”值,因为我只知道运行时的类型。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

问题是绑定器将使用您尝试分配给属性的值的 static 类型 - 而您想要动态地执行此操作。您需要做的就是将变量更改为dynamic类型,并且它可以工作:

dynamic myBool = obj.GetType().GetProperty("MyBool").GetValue(obj);
dynamic myInt = obj.GetType().GetProperty("MyInt").GetValue(obj);
dynamic myStr = obj.GetType().GetProperty("MyStr").GetValue(obj);

基本上,动态类型将与编译时类型为dynamic的任何表达式一起动态工作,但在执行该绑定时将使用任何其他表达式的编译时类型。