反射给对象赋值遇到的问题——类型转换【转】
转自http://blog.csdn.net/xiaohan2826/article/details/8536074
给一个对象属性赋值可以通过PropertyInfo.SetValue()方式进行赋值,但要注意值的类型要与属性保持一致。
创建对象实例的两种方法:
1.
1
|
var obj = Assembly.Load( "AssemblyName" ).CreateInstance( "AssemblyName" + "ClassFullName" ); |
2.
1
|
var obj = Activator.CreateInstance(ClassType); |
以后有时间再把这两种的区别详细讲一下。
创建好实例时,现在可以给当前实例的某个属性赋值,首先获取要赋值的属性。
1
|
var property = obj.GetType().GetProperty( "PropertyName" ); //此时可以使用GetProperty获取属性数组,循环进行赋值,这里主要讲解类型问题。 |
赋值可通过PropertyInfo.SetValue()方法,详见MSDN。
情况1,该属性类型是已知类型,例如:int
1
2
|
int value=500; property.SetValue(obj,value, null ); |
这里需要注意value值的类型必须和属性类型一致,否则会抛出TargetException异常。
情况2,该属性类型是已知类型,原值是其他类型。例如:目标类型为int,值为string
1
2
|
string value= "500" ; property.SetValue(obj, int .TryParse(value), null ); //类型转换。 |
前两种情况都很简单,有时业务会比较复杂,对目标类型不确定,需要程序运行时判断。
情况3,该属性类型是未知非泛型类型,不确定目标类型,如何进行类型转换。
1
2
|
object value= "500" ; property.SetValue(obj,Convert.ChangeType(value,property.PropertyType), null ); //类型转换。 |
这样就可以解决大多数问题了。
不知道大家有没有注意,我在第三种情况强调了非泛型,难道泛型就不行了吗? 是的。如果只是用Convert.ChangeType()方法,类型转换仍然报错,即使目标类型和值的类型是一致,通过Convert.ChangeType()进行转换仍然报错。
解决这个问题,就要先把属性值类型转成基类型后,在进行Convert转换
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); } }
本博客文章皆出于学习目的,个人总结或摘抄整理自网络。引用参考部分在文章中都有原文链接,如疏忽未给出请联系本人。另外,作为一名菜鸟程序媛,如文章内容有错误,欢迎点击博客右上方的扣扣链接指导交流。