C# PropertyInfo和MethodInfo跟AttributeInfo
前言
所謂的methodinfo和propertyinfo是因為我在重構程式碼的時候,但又不想去改到提供核心的code,但在原始核心有很多重複的程式碼,所以我使用泛型來處理,但正常狀況來說,這種會使用介面來實作比較理想,畢竟用泛型強制取出屬性和方法,皆是弱型別的方式,必須要等到runtime的時候,才會發現是否有錯誤,但遇到特殊的情況,或許還是得會需要這樣做,在此我紀錄一下,以備自己以後可以查閱。
PropertyInfo
先從泛型類別說起,當我想要傳入一個類別至我定義的泛型時,有時候免不了要建立一個物件,首先我們必須把泛型定義成class還有可以new的
public abstract class ProtectedRateBase<T, T1>
where T : class //只傳入類別
where T1 : class,new() //傳入類別並且可以建一個新物件
{
}
如果想要把泛型new成一個物件,就直接用泛型來建立一個物件
T1 Deal = new T1();
如果要取得屬性的話,就得先取得類別Type,才能取得屬性值,設定屬性值,或者取得所有的屬性值,然後用迴圈再裡面做處理
StringBuilder textBuilder = new StringBuilder();
T1 Deal = new T1();//建立物件
Type DealType = Deal.GetType();//取得物件的型別
DealType.GetProperty("Basis").GetValue(Deal);//取得屬性的值
DealType.GetProperty("Basis").SetValue(Deal, "1234");//寫入屬性的值
foreach (var item in DealType.GetProperties())
{
textBuilder.AppendFormat("屬性名稱{0},屬性的值{1}", item.Name, item.GetValue(Deal));
}
MethodInfo
當我們要調用方法的時候,也是得先把物件建立起起,然後取得物件型別
T tmp = new T();
MethodInfo[] methods = tmp.GetType().GetMethods(); //可以取得所有method
foreach (MethodInfo info in methods)
{
if (info.Name == "Win") //判斷method名稱
{
info.Invoke(tmp, null); //調用method
}
}
不過上面的方法其實有缺點,因為我們在調用方法的時候,其實常常都會有順序上的問題,甚至還有多型的問題,所以我會改成以下的寫法
T tmp = new T();
MethodInfo[] methods = tmp.GetType().GetMethods(); //可以取得所有method
tmp.GetType().GetMethod("method1").Invoke(tmp,null);
tmp.GetType().GetMethod("method2").Invoke(tmp,null);
methods.FirstOrDefault(x => x.Name == "metho3" && x.GetParameters().Count() == 13).Invoke(tmp,"要傳進去的參數");//會有多個同名稱的方法,所以我判斷多少參數來決定呼叫哪一個
AttributeInfo
在此我只是想把泛型的attribute取出來,所以我只需要首先取得所有屬性,然後就可以去抓各自的attribute來做處理了,下面是一個簡單的範例code
foreach (var prop in typeof(ChangePasswordDto).GetProperties())
{
object[] attrs = prop.GetCustomAttributes(true); //取得所有自訂attribute
if (attrs == null || attrs.Length == 0) continue;
foreach (Attribute attr in attrs)
{
if (attr is DisplayAttribute)
{
string context = (attr as DisplayAttribute).Name;//取得Display的Name的文字
}
}
}
以上如果有更好的做法,再請告知,也供自己備忘未來可以回顧。