<long> 使用反射将 int 设置为 Null 失败


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

这是正确的行为。

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

testObj.LongValue = intValue;

编译器解释它的方式就像你写

一样
testObj.LongValue = (long)intValue;

因为它知道LongValue的类型是long

另一方面,

Reflection是一个相当低级的API,因此它不会为您插入不必要的转换*,因此您需要在代码中添加强制类型转换。

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

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

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

相关内容

  • 没有找到相关文章

最新更新