使用refection将int设置为Nullable <long>失败</long>

时间:2014-08-06 10:31:59

标签: c# .net reflection

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]'。

2 个答案:

答案 0 :(得分:4)

这是正确的行为。

直接赋值和setter的基于反射的调用之间的区别在于,直接赋值编译器知道所分配属性的类型,并为您插入适当的转换。换句话说,当你写这个

testObj.LongValue = intValue;

编译器以与编写

相同的方式解释它
testObj.LongValue = (long)intValue;

因为它知道LongValue属于long类型。

另一方面,反射是一个相当低级的API,因此它不会为您插入无偿转换 * ,因此您需要在代码中添加强制转换。

* 由于值类型的所有参数在通过反射调用期间都经过装箱和拆箱,因此恰好是装箱类型的转换将成功。例如,传递long代替Nullable<long>参数是有效的,因为该值会经过装箱转换。

答案 1 :(得分:0)

您需要将其转换为设置值之前的类型。

long? temp = intValue;
propInfo.SetValue(testObj, temp);