C#利用反射给对象赋值


我们如果想利用凡是给一个对象属性赋值可以通过PropertyInfo.SetValue()方式进行赋值,但要注意值的类型要与属性保持一致,例如:

var property = obj.GetType().GetProperty(“PropertyName”);//此时可以使用GetProperty获取属性数组,循环进行赋值。

该属性类型是已知基本类型可以直接将变量传入, 例如:string

var value=”wangheng.org”;

property.SetValue(obj,value,null);

这里需要注意value值的类型必须和属性类型一致,否则会抛出TargetException异常。

如果原值是其他类型。例如:目标类型为int,值为string

string value=”100”;

property.SetValue(obj,int.TryParse(value),null);//类型转换。

上面几种都比较容易处理,但是如果该属性类型是未知非泛型类型,例如 int?

var value=”100”;

property.SetValue(obj,Convert.ChangeType(value, property.PropertyType), null);//类型转换。这时简单调用 ChangeType()方法,类型会报错。

想解决这个问题,需要首先把属性值类型转成基本类型,然后进行转换。如下:
            if (!property.PropertyType.IsGenericType)
{
//非泛型
property.SetValue(obj, string.IsNullOrEmpty(value) ? null : Convert.ChangeType(value, property.PropertyType), null);
}
else
{
//泛型Nullable<>
Type genericTypeDefinition = property.PropertyType.GetGenericTypeDefinition();
if (genericTypeDefinition == typeof(Nullable<>))
{
property.SetValue(obj, string.IsNullOrEmpty(value) ? null : Convert.ChangeType(value, Nullable.GetUnderlyingType(property.PropertyType)), null);
}
}

这样,在使用Convert.ChangeType()转换可空类型时,就不会报错了。