1. 程式人生 > >C# 反射給物件屬性賦值遇到的問題——型別轉換

C# 反射給物件屬性賦值遇到的問題——型別轉換

建立物件例項的兩種方法: 

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獲取屬性陣列,迴圈進行賦值,這裡主要講解型別問題。

情況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轉換。看程式碼


這樣,在使用Convert.ChangeType()轉換可空型別時,就不會報錯了。
再增加一些基礎的判斷驗證,程式碼就比較完善了。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 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); } }