public class Test
{
public long? LongValue { get; set; }
}
//----------
var propInfo = typeof(Test).GetProperties(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(p => p.Name == "LongValue");
//propInfo of Test.LongValue property
if (propInfo != null)
{
int intValue = 99;
var testObj = new Test();
testObj.LongValue = intValue; //This line succeeds
propInfo.SetValue(testObj, intValue); //This throws System.ArgumentException
}
propInfo.SetValue在直接赋值成功的情况下抛出以下异常。
发生了'System.ArgumentException'类型的未处理异常 mscorlib.dll中
附加信息:'System.Int32'类型的对象不能 转换为类型'System.Nullable`1 [System.Int64]'。
答案 0 :(得分:4)
这是正确的行为。
直接赋值和setter的基于反射的调用之间的区别在于,直接赋值编译器知道所分配属性的类型,并为您插入适当的转换。换句话说,当你写这个
testObj.LongValue = intValue;
编译器以与编写
相同的方式解释它testObj.LongValue = (long)intValue;
因为它知道LongValue
属于long
类型。
* 由于值类型的所有参数在通过反射调用期间都经过装箱和拆箱,因此恰好是装箱类型的转换将成功。例如,传递long
代替Nullable<long>
参数是有效的,因为该值会经过装箱转换。
答案 1 :(得分:0)
您需要将其转换为设置值之前的类型。
long? temp = intValue;
propInfo.SetValue(testObj, temp);