使用反射为动态类型赋值并绕过 GetValue returns 的对象 cast\box
Assigning a value to a dynamic type using reflection and bypassing the object cast\box that GetValue returns
我有两个具有完全相同属性的对象。这是一个例子:
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
的实例。
作为任务的一部分,我需要从 MainObject
的实例中获取 Value
。
因为我不知道编译类型中当前属性的类型,所以我使用的是动态变量。
这是一个简短的例子(这 不是 代码在现实生活中的样子 - 这个例子是为了简化 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;
现在我遇到了这个异常:
Cannot implicitly convert type 'object' to 'bool?'. An explicit
conversion exists (are you missing a cast?)
我明白为什么会出现异常,我正在尝试寻找解决方法。
我知道 currentField.Value
和 val
值应该是同一类型。
我的问题是使用反射(GetValue
returns 和 object
)自动将值 casts\boxes 转换为 object
并破坏了我的计划。
我无法转换为 "correct" 值,因为我只知道运行时的类型。
我该如何解决这个问题?
问题在于活页夹将使用您尝试分配给 属性 的 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
的任何表达式,但会使用任何 other 表达式的编译时类型在执行该绑定时。
我有两个具有完全相同属性的对象。这是一个例子:
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
的实例。
作为任务的一部分,我需要从 MainObject
的实例中获取 Value
。
因为我不知道编译类型中当前属性的类型,所以我使用的是动态变量。
这是一个简短的例子(这 不是 代码在现实生活中的样子 - 这个例子是为了简化 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;
现在我遇到了这个异常:
Cannot implicitly convert type 'object' to 'bool?'. An explicit conversion exists (are you missing a cast?)
我明白为什么会出现异常,我正在尝试寻找解决方法。
我知道 currentField.Value
和 val
值应该是同一类型。
我的问题是使用反射(GetValue
returns 和 object
)自动将值 casts\boxes 转换为 object
并破坏了我的计划。
我无法转换为 "correct" 值,因为我只知道运行时的类型。
我该如何解决这个问题?
问题在于活页夹将使用您尝试分配给 属性 的 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
的任何表达式,但会使用任何 other 表达式的编译时类型在执行该绑定时。