设置属性可空<>由反射(Set property Nullable<> by re

2019-07-19 22:11发布

我尝试设置一个可空<>属性动态地。

我把我的财产例如:

PropertyInfo property = class.GetProperty("PropertyName"); // My property is Nullable<> at this time So the type could be a string or int

我想通过反射设置我的财产一样

property.SetValue(class,"1256",null);

当我的属性是可空<>一般它不工作。 所以,我试图找到一种方法来设置我的财产。

要知道我执行我可空<>属性的类型

Nullable.GetUnderlyingType(property.PropertyType)

任何的想法 ?

  • 我尝试创建我可空<>属性的一个实例与

    VAR nullVar = Activator.CreateInstance(typeof运算(可空<>)MakeGenericType(新类型[] {Nullable.GetUnderlyingType(property.PropertyType)})。);

但是nullVar总是空

Answer 1:

如果您想要的任意字符串转换为基本类型的可空的,你可以使用Convert类:

var propertyInfo = typeof(Foo).GetProperty("Bar");
object convertedValue = null;
try 
{ 
    convertedValue = System.Convert.ChangeType("1256", 
        Nullable.GetUnderlyingType(propertyInfo.PropertyType));
} 
catch (InvalidCastException)
{
    // the input string could not be converted to the target type - abort
    return;
}
propertyInfo.SetValue(fooInstance, convertedValue, null);

这个例子将工作,如果目标类型是int,短的,长(或无符号的变体中,由于输入字符串代表一个非负号),双,浮点,或小数。 警告:这是不是快的代码。



Answer 2:

如果它是一个可空INT,你需要使用一个int参数,而不是字符串。

 property.SetValue(klass,1256,null);

注意改变克拉斯,而不是类,类是保留关键字。 你也可以使用@class在绝对必要的(引用它)。

如果你的财产是一个通用的,那么我想你可能需要使用转换为任何你必须转换成任何你需要的。

 var nullType = Nullable.GetUnderlyingType(property.PropertyType)
 var value = Convert.ChangeType("1256", nullType );
 property.SetValue(klass, value, null );


Answer 3:

这里是展示如何做一个完整的例子:

using System;
using System.Reflection;

class Test
{
    static void Main()
    {
        Foo foo = new Foo();
        typeof(Foo).GetProperty("Bar")
            .SetValue(foo, 1234, null);
    }
}

class Foo
{
    public Nullable<Int32> Bar { get; set; }
}

正如其他人所说,你需要正确的类型传递到SetValue功能,但你的其他反射代码是不完全正确要么。 你需要得到有关类别的类型,然后才能查询其成员。

编辑:如果我理解正确你想设置一个字符串值,以通过反射的任何财产。 为了做到这一点,你需要做一些类型的检查和类型转换。

这里是我的意思的例子:

using System;
using System.Reflection;

class Test
{
    static void Main()
    {
        Foo foo = new Foo();

        PropertyInfo property = typeof(Foo).GetProperty("Bar");
        Object value =
            Convert.ChangeType("1234",
                Nullable.GetUnderlyingType(property.PropertyType)
                ?? property.PropertyType);

        property.SetValue(foo, value, null);
    }
}

class Foo
{
    public Nullable<Int32> Bar { get; set; }
}

这种方法可以安全地使用而不管属性是否是Nullable<>



Answer 4:

"1256"是一个字符串,而不是一个int。



Answer 5:

我打这个同样的问题,以及与Convert.ChangeType不是Nullables处理DateTime是否的问题,所以我联合几个计算器解决方案的一些.NET 4动态魔术得到的东西,我认为是一种甜蜜。 如果你看一下代码,我们使用动态在运行时键入对象为空,则运行时会将其不同,允许基本类型的可空对象的分配。

public void GenericMapField(object targetObj, string fieldName, object fieldValue)
{
    PropertyInfo prop = targetObj.GetType().GetProperty(fieldName);
    if (prop != null)
    {
        if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            dynamic objValue = System.Activator.CreateInstance(prop.PropertyType);
            objValue = fieldValue;
            prop.SetValue(targetObj, (object)objValue, null);
        }
        else
        {
            prop.SetValue(targetObj, fieldValue, null);
        }
    }
}


Answer 6:

public static void SetValue(object target, string propertyName, object value)
{
  if (target == null)
    return;

  PropertyInfo propertyInfo = target.GetType().GetProperty(propertyName);

  object convertedValue = value;
  if (value != null && value.GetType() != propertyInfo.PropertyType)
  {
    Type propertyType = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
    convertedValue = Convert.ChangeType(value, propertyType);
  }

  propertyInfo.SetValue(target, convertedValue, null);
}


文章来源: Set property Nullable<> by reflection