代码之家  ›  专栏  ›  技术社区  ›  Cédric Boivin

通过反射将属性设置为Nullable<>

  •  11
  • Cédric Boivin  · 技术社区  · 17 年前

    我尝试设置一个可为null的<&燃气轮机;动态的属性。

    我得到我的财产:

    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);
    

    当我的属性为可空时,它不起作用<&燃气轮机;通用的因此,我试图找到一种方法来设置我的属性。

    要知道我的可为null的类型<&燃气轮机;我执行的财产

    Nullable.GetUnderlyingType(property.PropertyType)
    

    有什么想法吗?

    但是nullVar总是空的

    6 回复  |  直到 17 年前
        1
  •  17
  •   Ben M    17 年前

    如果要将任意字符串转换为Nullable的基础类型,可以使用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、short、long(或无符号变量,因为输入字符串表示非负数)、double、float或decimal,则此示例将起作用。警告:这不是快速代码。

        2
  •  9
  •   tvanfosson    17 年前

     property.SetValue(klass,1256,null);
    

    注意更改为klass,而不是class,因为class是保留关键字。如果绝对必要,您也可以使用@class(引用它)。

    如果您的属性是泛型的,那么我认为您可能需要使用Convert将所有内容转换为所需内容。

     var nullType = Nullable.GetUnderlyingType(property.PropertyType)
     var value = Convert.ChangeType("1256", nullType );
     property.SetValue(klass, value, null );
    
        3
  •  5
  •   Andrew Hare    17 年前

    下面是一个完整的示例,演示如何执行此操作:

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

        4
  •  3
  •   AdamCrawford    14 年前

    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);
            }
        }
    }
    
        5
  •  2
  •   Steve Gilham    17 年前

    "1256"

        6
  •  1
  •   czlatea    12 年前
    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);
    }