日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

談談:程序集加載和反射

 昵稱10504424 2012-08-16

最近一直都在看關于程序集加載和反射方面的資料, 所以在這里把我所學習到的東西記錄下來,方便自己以后復習,也給園子里面不懂的朋友參考。

一、程序集的加載

JIT編譯器器將IL代碼編譯成本地代碼時, 會查看IL代碼中引用了哪些類型。在運行過程中,JIT編譯器利用程序集的TypeRef和AssemblyRef元數據表來確定哪一個程序集定義了所引用的類型,然后JIT編譯器將對應程序集加載到AppDomain中,在內部,CLR使用System.Reflection.Assembly類的靜態(tài)方法Load來嘗試加載一個程序集。然而如果我們想動態(tài)加載一個程序集時,可以使用Assembly的Load方法來動態(tài)加載程序集,其中Assembly類中還提供了其他的加載程序集方法,有LoadFrom(string path), LoadFile(stringassemblyFile)等,具體方法的使用和解釋可以參照MSDN中的介紹:http://msdn.microsoft.com/zh-cn/library/xbe1wdx9

 

二、反射機制

.net中反射在運行中過程中解析程序集中的元數據,獲得類型中的成員(包括字段、構造器、方法、屬性、事件等)信息。

動態(tài)加載一個程序集并獲得類型中的成員

把下面的類放在一個類庫工程中,并編譯生成程序集(例如為ClassLibrary1.dll,假設把dll放在D盤根目錄下面)

View Code
復制代碼
 1  public class ReflectTestClass
 2     {
 3        public  string name;
 4        public int age;
 5        public string Name
 6        {
 7            get { return name; }
 8            set { name = value; }
 9        }
10 
11        public int Age
12        {
13            get { return age; }
14            set { age = value; }
15        }
16 
17         /// <summary>
18         /// No Paramter Constructor
19         /// </summary>
20        public ReflectTestClass()
21        { 
22        }
23 
24         /// <summary>
25         /// Constructor with Parameter
26         /// </summary>
27         /// <param name="name"></param>
28         /// <param name="age"></param>
29         public ReflectTestClass(string names,int ages)
30         {
31             this.name = names;
32             this.age = ages;
33         }
34 
35         public string writeString(string name)
36         {
37             return "Welcome " + name;
38         }
39 
40         public static string WriteName(string name)
41         {
42             return "Welcome "+name +" Come here";
43         }
44 
45         public string WirteNopara()
46         {
47             return "The method is no parameter ";
48         }
49     }
復制代碼

然后建立一個控制臺程序用來動態(tài)加載上面生成的程序集和輸出類型中的成員,代碼中有詳細的介紹。

復制代碼
class Program
    {
        static void Main(string[] args)
        {
            Assembly ass;
            Type[] types;
            Type typeA;
            object obj;
            try
            {
                // 從本地中 加載程序集 然后從程序集中通過反射獲得類型的信息的,并且調用方法
                ass = Assembly.LoadFrom(@"D:\ClassLibrary1.dll");
                types = ass.GetTypes();
                foreach (Type type in types)
                {
                    Console.WriteLine("Class Name is " + type.FullName);
                    Console.WriteLine("Constructor Information");
                    Console.WriteLine("-----------------------");
                    // 獲取類型的結構信息
                    ConstructorInfo[] myconstructors = type.GetConstructors();
                    ShowMessage<ConstructorInfo>(myconstructors);

                    Console.WriteLine("Fields Information");
                    Console.WriteLine("-----------------------");
                    // 獲取類型的字段信息
                    FieldInfo[] myfields = type.GetFields();
                    ShowMessage<FieldInfo>(myfields);

                    Console.WriteLine("All Methods Information");
                    Console.WriteLine("-----------------------");
                    // 獲取方法信息
                    MethodInfo[] myMethodInfo = type.GetMethods();
                    ShowMessage<MethodInfo>(myMethodInfo);

                    Console.WriteLine("All Properties Information");
                    Console.WriteLine("-----------------------");
                    // 獲取屬性信息
                    PropertyInfo[] myproperties = type.GetProperties();
                    ShowMessage<PropertyInfo>(myproperties);
                }

                // 用命名空間+類名獲取類型
                typeA = ass.GetType("ClassLibrary1.ReflectTestClass");
                
                // 獲得方法名稱

                MethodInfo method = typeA.GetMethod("writeString");

                // 創(chuàng)建實例
                obj = ass.CreateInstance("ClassLibrary1.ReflectTestClass");

                string result = (String)method.Invoke(obj,new string[] {"Tom"});
                Console.WriteLine("Invoke Method With Parameter");
                Console.WriteLine("-----------------------");
                Console.WriteLine(result);
                Console.WriteLine("-----------------------");
                Console.WriteLine();
                method = typeA.GetMethod("WriteName");
                result = (string)method.Invoke(null,new string[] {"Tom"});
                Console.WriteLine("Invoke Static Method with Parameter");
                Console.WriteLine("-----------------------");
                Console.WriteLine(result);
                Console.WriteLine("-----------------------");
                Console.WriteLine();
                method = typeA.GetMethod("WirteNopara");
                Console.WriteLine("Invoke Method with NOParameter");
                result = (string)method.Invoke(obj, null);
                Console.WriteLine("-----------------------");
                Console.WriteLine(result);
                Console.WriteLine("-----------------------");
            }

            catch(FileNotFoundException ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.ReadLine();
        }

        /// <summary>
        /// 顯示數組信息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="os"></param>
        public static void ShowMessage<T>(T[] array)
        { 
            foreach(T member in array)
            {
                Console.WriteLine(member.ToString());
            }

            Console.WriteLine("-----------------------");
            Console.WriteLine();
        }
    }
復制代碼


篩選返回的成員種類

可以調用Type的GetMembers,GetFields,GetMethods,GetProperties或者GetEvenents方法來查詢一個類型的成員。在調用上面的任何一個方法時,都可以傳遞System.Reflection.BindingFlags枚舉類型的一個實例,使用這個枚舉類型目的是對這些方法返回的成員進行篩選。對于這個枚舉類型中成員的信息可以參考MSDN:http://msdn.microsoft.com/zh-cn/library/system.reflection.bindingflags(v=VS.80).aspx

注意:在返回一個成員集合的所有方法中, 都有一個不獲取任何實參的重載版本。如果不傳遞BindingFlags實參,所有這些方法都返回公共成員,默認設置為BindingFlags.Public|BindingFlags.Instance|BindingFlags.Static. (如果指定Public或NonPublic,那么必須同時指定Instance,否則不返回成員)。

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多