反射給對象賦值——類型轉換
阿新 • • 發佈:2017-09-09
-1 microsoft 比較 lai pan eof code edit cti
文章轉自: http://blog.csdn.net/xiaohan2826/article/details/8536074
反射給對象賦值遇到的問題——類型轉換
發布時間:2012-10-25 10:49瀏覽次數:225 給一個對象屬性賦值可以通過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轉換。看代碼
這樣,在使用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 );
}
}
|
反射給對象賦值——類型轉換