[C#] PropertyInfo和MethodInfo跟AttributeInfo

  • 1881
  • 0
  • C#
  • 2015-09-20

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的文字
                    }
                }
            }

 

以上如果有更好的做法,再請告知,也供自己備忘未來可以回顧。