通过反射设置属性时键入转换问题

Shi*_*kyo 25 c# reflection

我们有一个类型的属性,long?充满了int.

当我直接设置属性obj.Value = v;但是当我尝试通过反射设置属性时,这工作正常,info.SetValue(obj, v, null);它给了我以下异常:

'System.Int32'类型的对象无法转换为'System.Nullable`1 [System.Int64]'类型.

这是一个简化的场景:

    class TestClass
    {
        public long? Value { get; set; }
    }

    [TestMethod]
    public void TestMethod2()
    {
        TestClass obj = new TestClass();
        Type t = obj.GetType();

        PropertyInfo info = t.GetProperty("Value");
        int v = 1;

        // This works
        obj.Value = v;

        // This does not work
        info.SetValue(obj, v, null);
    }
Run Code Online (Sandbox Code Playgroud)

为什么在直接设置属性时设置属性reflection时它不起作用?

Pra*_*ana 66

查看全文: 如何使用Reflection设置属性的值?

如果要为可空类型设置值,则为完整代码

public static void SetValue(object inputObject, string propertyName, object propertyVal)
{
    //find out the type
    Type type = inputObject.GetType();

    //get the property information based on the type
    System.Reflection.PropertyInfo propertyInfo = type.GetProperty(propertyName);

    //find the property type
    Type propertyType = propertyInfo.PropertyType;

    //Convert.ChangeType does not handle conversion to nullable types
    //if the property type is nullable, we need to get the underlying type of the property
    var targetType = IsNullableType(propertyType) ? Nullable.GetUnderlyingType(propertyType) : propertyType;

    //Returns an System.Object with the specified System.Type and whose value is
    //equivalent to the specified object.
    propertyVal = Convert.ChangeType(propertyVal, targetType);

    //Set the value of the property
    propertyInfo.SetValue(inputObject, propertyVal, null);

}
private static bool IsNullableType(Type type)
{
    return type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>));
}
Run Code Online (Sandbox Code Playgroud)

你需要转换这样的值,即你需要将值转换为你的属性类型,如下所示

PropertyInfo info = t.GetProperty("Value");
object value = null;
try 
{ 
    value = System.Convert.ChangeType(123, 
        Nullable.GetUnderlyingType(info.PropertyType));
} 
catch (InvalidCastException)
{
    return;
}
propertyInfo.SetValue(obj, value, null);
Run Code Online (Sandbox Code Playgroud)

你需要这样做,因为你不能将任何arbirtary值转换为给定类型...所以你需要像这样转换它