C#反射

來源:互聯網
上載者:User

標籤:sof   關機   object   tor   dir   reac   str   psi   判斷   

反射的概念: 反射提供了封裝程式集、模組和類型的對象(Type類型)。可以使用反射動態建立類型的執行個體,將類型綁定到現有對象,或從現有對象擷取類型並調用其方法或訪問其欄位和屬性。如果代碼中使用了屬性,可以利用反射對它們進行訪問。

一般使用:    工廠類,通過反射建立類的執行個體,實現層與層之間的解耦:  資料層→資料會話層→商務邏輯層。 其中,資料會話層通過反射建立資料層的執行個體,商務邏輯層調用。

 

反射Type中的函數
//判斷兩個成員是否存在繼承關係    --後者繼承於前者bool b= typeof(Person).IsAssignableFrom(typeof(Student));    //student繼承了person//判斷當前類是否為對象的執行個體Student st = new Student();Person p = new Person();bool s = typeof(Person).IsInstanceOfType(st);     //student繼承了person  結果為true bool b = p.GetType().IsInstanceOfType(st);   //結果為true   GetType當前對象的執行個體//判斷一個類是否為另外一個類的子類    --子類放先 bool c=    typeof(Person).IsSubclassOf(typeof(Student));  //判斷一個類是否為抽象類別typeof(Class).IsAbstract

 

反射中常用類的使用

需求:通過反射獲得Common程式集中的成員,並使用成員

1、把Common.dll放到該應用程式的bin/Debug目錄下

string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Common.dll");Assembly ass = Assembly.LoadFile(path);  //需要絕對路徑  LoadFile載入路徑程式集內容        -->也不一定要在debug目錄下,自己構建絕對路徑也可Type[] tp = ass.GetTypes();             //獲得程式集中的所有類型    GetExportedTypes();擷取公用類型

2、可以遍曆程式集中的類型,擷取類型的命名空間和類型名稱

foreach (Type item in tp){     Console.WriteLine(item.Name);             //類型名稱  --也就是common下類或者介面的名稱    Console.WriteLine(item.Namespace);        //命名空間
}

 

3、建立type對象

      a:建立沒有建構函式的對象

object o=  ass.CreateInstance("Common.FileCommon");     //FileCommom為Common命名空間的一個類 → 命名空間.類名   

    b:反射出來的類型有建構函式

 Type type = ass.GetType("Common.FileCommon");    //獲得指定名稱的Type對象 object o = Activator.CreateInstance(type, "參數");

註: 當反射出來的類型如果有建構函式,用上面代碼中 ass.CreateInstance則會出現錯誤,如果有建構函式,那麼該如何知道建構函式的參數?

 ConstructorInfo [] info= type.GetConstructors();    //查詢所有的建構函式,可以看到建構函式需要傳遞參數的參數類型

 

4、獲得資料類型中所有的屬性

 PropertyInfo  [] pinfo   = type.GetProperties();   //擷取屬性  然後可以遍曆

 

5、獲得資料類型中所有的函數

MethodInfo [] minfo =type.GetMethods();   //擷取所有的函數

 

6、目的:調用函數

 MethodInfo method= type.GetMethod("WriteData");    //該類中的writeData方法 method.Invoke(o, "writeData方法的參數");     //o為上文建立的type對象

 

綜合: 當獲得一個  .dll程式集的時候,需要先擷取所有的類型,也就是這個程式集中的類,然後根據所需要類的名稱,去建立指定名稱的對象 如:Type type = ass.GetType("Common.FileCommon");  ,然後利用type擷取建構函式,所有函數,屬性(還有一些可以 type.方法名  擷取相應的需求)。再選擇建立type對象的方法(構造或無構造)。然後根據獲得的函數來調用,傳入相應的參數。

 

執行個體1:工廠類通過反射建立類的執行個體:

步驟①:在Web.Config    (網頁的為web.config,程式中為app.config) ,設定檔配置:

 <appSettings><add key="AssemblyPath" value="Xsh.OA.DAL" />   //路徑<add key="NameSpace" value="Xsh.OA.DAL" />     //命名空間</appSettings>

步驟②:擷取剛才配置的資訊

public static readonly string AssemblyPath = ConfigurationManager.AppSettings["AssemblyPath"];public static readonly string NameSpace = ConfigurationManager.AppSettings["NameSpace"];

步驟③:建立類的執行個體:

 public static IUserInfoDal CreateUserInfoDal() {    string fullClassName = NameSpace + ".UserInfoDal";     return  CreateInstance(fullClassName) as IUserInfoDal;         //IUserInfoDal為UserInfoDal繼承的介面。 }  private static object CreateInstance(string className)  {            var assembly= Assembly.Load(AssemblyPath);            return assembly.CreateInstance(className);  }//此時,在外界調用CreateUserInfoDal這個方法,就會建立了UserInfoDal的執行個體,然後根據該執行個體 點出方法

 

執行個體2:使用反射製作關機外掛程式

特點:如果需要其他外掛程式,添加路徑下的 .dll檔案即可,刪除外掛程式則刪除相應的.dll檔案

            //獲得檔案路徑            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"plug");   //bin/debug/plug存放.dll檔案            string[] files = Directory.GetFiles(path);            foreach (string item in files)            {               Assembly ass = Assembly.LoadFile(item);                  Type [] types=  ass.GetExportedTypes();                for (int i = 0; i < types.Length; i++)                {                    //判斷是否為介面中的類,並不是抽象類別                    if (typeof(IPlugin).IsAssignableFrom(types[i]) && !types[i].IsAbstract)                    {                        //建立對象                        object  o =  Activator.CreateInstance(types[i]);                        //獲得指定對象                        PropertyInfo psi=   types[i].GetProperty("Name");                        object o2=  psi.GetValue(o);                        //添加到功能表列(這是winform下的一個功能表列控制項)                        ToolStripItem tsi= PluginToolStripMenuItem.DropDownItems.Add(o2.ToString());                        //註冊單擊事件                         tsi.Tag = types[i];    //把資料Object Storage Service到要使用的對象                                                //  tsi.Click += Tsi_Click;                        tsi.Click += (s, e2) => {                            Type t = tsi.Tag as Type;                            MethodInfo mi = t.GetMethod("DoIt");                            mi.Invoke(o, new object[] { });                        };                    }                }

 

總結:  很多.dll檔案可以通過反射的方式來擷取相應的類,類的方法屬性的使用,一些應用程式也可以通過反編譯軟體來擷取一些方法屬性等。(後面如果使用到另外用途,再加補充)

 

C#反射

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.