通过反射设置属性Nullable <>

Céd*_*vin 12 c# generics reflection nullable activator

我尝试动态设置Nullable <>属性.

我得到我的房产前:

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

我想用反射来设置我的属性

property.SetValue(class,"1256",null);
Run Code Online (Sandbox Code Playgroud)

当我的属性是Nullable <> Generic时,它不起作用.所以我试图找到一种方法来设置我的财产.

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

Nullable.GetUnderlyingType(property.PropertyType)
Run Code Online (Sandbox Code Playgroud)

任何的想法 ?

  • 我尝试用我的Nullable <>属性创建一个实例

    var nullVar = Activator.CreateInstance(typeof(Nullable <>).MakeGenericType(new Type [] {Nullable.GetUnderlyingType(property.PropertyType)}));

但是nullVar总是空的

Ben*_*n M 16

如果要将任意字符串转换为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);
Run Code Online (Sandbox Code Playgroud)

如果目标类型是int,short,long(或无符号变量,因为输入字符串表示非负数),double,float或decimal,则此示例将起作用.警告:这不是快速代码.


tva*_*son 9

如果它是一个可以为null的int,则需要使用int参数,而不是字符串.

 property.SetValue(klass,1256,null);
Run Code Online (Sandbox Code Playgroud)

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

如果您的属性是通用的,那么我认为您可能需要使用转换将您拥有的任何内容转换为您需要的任何内容.

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

  • 你不能有一个`Nullable <string>`,因为`string`不是一个值类型. (2认同)

And*_*are 5

这是一个完整的示例,说明如何执行此操作:

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; }
}
Run Code Online (Sandbox Code Playgroud)

正如其他人提到的那样,你需要将正确的类型传递给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; }
}
Run Code Online (Sandbox Code Playgroud)

无论财产是否属实,都可以安全地使用这种方法Nullable<>.