首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >通过反射设置属性时的类型转换问题

通过反射设置属性时的类型转换问题
EN

Stack Overflow用户
提问于 2012-11-07 20:52:17
回答 8查看 44K关注 0票数 31

我们有一个用int填充的long?类型的属性。

当我直接将属性设置为obj.Value = v;时,这种方法工作得很好,但是当我尝试通过反射info.SetValue(obj, v, null);来设置属性时,它会给出以下异常:

'System.Int32‘类型的

对象不能转换为'System.Nullable`1System.Int64’类型。

这是一个简化的场景:

代码语言:javascript
复制
    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);
    }

为什么通过reflection设置属性时不起作用,而直接设置属性时起作用?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2012-11-07 20:59:39

查看全文:How to set value of a property using Reflection?

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

代码语言:javascript
复制
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<>));
}

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

代码语言:javascript
复制
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);

您需要这样做,因为您不能将任何任意值转换为给定的type...so,您需要像这样转换它

票数 77
EN

Stack Overflow用户

发布于 2012-11-07 21:01:07

当你写的时候:

代码语言:javascript
复制
obj.Value = v;

编译器知道如何为您进行适当的强制转换,并实际编译

代码语言:javascript
复制
obj.Value = new long?((long) v);

当您使用反射时,没有编译器可以帮助您。

票数 4
EN

Stack Overflow用户

发布于 2012-11-07 21:01:43

因为类型long具有隐式转换方法。

6.1.2 Implicit numeric conversions

您可以将隐式转换方法视为存在于=符号后面的隐藏方法。

它还适用于可空类型:

代码语言:javascript
复制
int i = 0;
int? j = i; // Implicit conversion
long k = i; // Implicit conversion
long? l = i; // Implicit conversion

但是反过来是行不通的,因为不存在将null传递给非null的隐式转换:

代码语言:javascript
复制
int? i = 0;
int j = i; // Compile assert. An explicit conversion exit... 
int k = (int)i; // Compile, but if i is null, you will assert at runtime.

您不必显式地将int转换为int?...或者是long?

但是,当您使用反射时,您将绕过隐式转换,并将值直接赋值给属性。这样,您必须显式地转换它。

代码语言:javascript
复制
info.SetValue(obj, (long?)v, null);

反射跳过隐藏在=后面的所有甜蜜的东西。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13270183

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档