1. 程式人生 > >c#之反射(Reflection)

c#之反射(Reflection)

是什麽 文件 實例 col odi invoke jdb cto lec

一、反射是什麽

  1. 反射就是.Net FrameWork框架為我們提供的一個幫助類庫,它可以讀取我們通過編譯後生成的dll和exe文件裏面metadate的信息。
  2. 反射可以動態的加載dll和exe文件,動態的創建對象,動態的調用方法,動態的獲取屬性的值和為屬性賦值等等......

二、通過反射獲取信息

在C#程序中,我們可以用 System.Reflection 命名空間下的 Assembly 類來加載dll文件,從而來獲取裏面的信息,代碼如下:

                    Assembly assembly = Assembly.Load("MyReflection.DB.SqlService
"); foreach (var item in assembly.GetModules()) { Console.WriteLine("Module完全限定名:" + item.FullyQualifiedName); } foreach (var type in assembly.GetTypes())//遍歷該dll下的所有類型 { Console.WriteLine(
"Type完全限定名:" + type.FullName); foreach (var item in type.GetConstructors())//遍歷類型下的所有構造函數 { Console.WriteLine(item.Name); } foreach (var item in type.GetMethods())//遍歷類型下的所有公開方法 { Console.WriteLine(item.Name); }
foreach (var item in type.GetProperties())//遍歷類型下的所有公開屬性 { Console.WriteLine(item.Name); } foreach (var item in type.GetFields())//遍歷類型下的所有公開字段 { Console.WriteLine(item.Name); } }

三、創建對象

上面我們可以獲取到dll中的信息,接下來我們就來使用一些信息來創建對象,來調用對象裏的方法。

                        Assembly assembly = Assembly.Load("MyReflection.DB.SqlService");//1.動態加載dll
                        Type typeHelper = assembly.GetType("MyReflection.DB.SqlService.SqlServerHelper");//2.獲取類型信息
                        object objDbHelper = Activator.CreateInstance(typeHelper);//3.創建對象
                        IDBHelper dbHelper = (IDBHelper)objDbHelper;
                        dbHelper.Query();

四、調用方法

通過上面我們知道要想調用方法,就必須先知道類型,然後強轉成相應的類型才能調用方法,接下來我們就來實現不需要知道類型就來調用一系列方法:

首先上面創建對象的三個步驟是少不了的。

     Assembly assembly = Assembly.Load("MyReflection.DB.SqlService");//1.動態加載dll
        Type typeHelper = assembly.GetType("MyReflection.DB.SqlService.ReflectionTest");//2.獲取類型信息
        object objDbHelper = Activator.CreateInstance(typeHelper);//3.創建對象

1、調用無參數的方法:

        public void show1() 
        {
            Console.WriteLine("這裏是{0}的show1", this.GetType());
        }

        MethodInfo show1 = typeHelper.GetMethod("show1");
        show1.Invoke(objDbHelper, null);

結果如下:

技術分享圖片

2、調用有參數的方法:

        public void show2(int id)
        {
            Console.WriteLine("這裏是{0}的show2", this.GetType());
        }
        MethodInfo show2 = typeHelper.GetMethod("show2");
        show2.Invoke(objDbHelper, new object[] { 11 });

結果如下:

技術分享圖片

3、調用有參數並且重載的方法:

     public void show3()
        {
            Console.WriteLine("這裏是{0}無參的show3", this.GetType());
        }
        public void show3(string name,int id)
        {
            Console.WriteLine("這裏是{0}帶string參數和int參數的show3", this.GetType());
        }
        public void show3(int id,string name)
        {
            Console.WriteLine("這裏是{0}帶int參數和string參數的show3", this.GetType());
        }
        public void show3(int id)
        {
            Console.WriteLine("這裏是{0}帶int參數的show3", this.GetType());
        }
        public void show3(string name)
        {
            Console.WriteLine("這裏是{0}帶string參數的show3", this.GetType());
        }


        MethodInfo show3_1 = typeHelper.GetMethod("show3", new Type[] { typeof(string) });
        show3_1.Invoke(objDbHelper, new object[] { "dafs" });

        MethodInfo show3_2 = typeHelper.GetMethod("show3", new Type[] { typeof(int) });
        show3_2.Invoke(objDbHelper, new object[] { 111 });

        MethodInfo show3_3 = typeHelper.GetMethod("show3", new Type[] { typeof(int), typeof(string) });
        show3_3.Invoke(objDbHelper, new object[] { 111, "dfafsd" });

結果如下:

技術分享圖片

4、調用有私有的方法:

        private void show4(string name)
        {
            Console.WriteLine("這裏是{0}的show4", this.GetType());
        }
        MethodInfo show4 = typeHelper.GetMethod("show4", BindingFlags.Instance |//訪問私有方法
            BindingFlags.Public | BindingFlags.NonPublic);
        show4.Invoke(objDbHelper, new object[] { "dfafsd" });

結果如下:

技術分享圖片

4、調用靜態的方法:靜態方法在調用的時候要不要對象都行,推薦不要放對象,原因就不說了,都懂的

        public static void show5(string name)
        {
            Console.WriteLine("這裏是{0}的show5", typeof(ReflectionTest));
        }
        MethodInfo show5 = typeHelper.GetMethod("show5");//靜態方法
        show5.Invoke(null, new object[] { "dfafsd" });//不放對象
        show5.Invoke(objDbHelper, new object[] { "dfafsd" });//放對象

結果如下:

技術分享圖片

五、為屬性賦值和設置值

接直來我們創建一個 People

    public class People
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

然後實例化:

                    People people = new People
                    {
                        Id = 1001,
                        Name = "張三"
                    };

接下來我們來獲取屬性值和設置屬性值:

                    Type type = typeof(People);
                    object oPeople = Activator.CreateInstance(type);
                    foreach (var item in type.GetProperties())//字段設置和獲取的語法和屬性一樣
                    {
                        Console.WriteLine("{0}={1}", item.Name, item.GetValue(oPeople));
                        if (item.Name.Equals("Id"))
                        {
                            item.SetValue(oPeople, 1002);
                        }
                        if (item.Name.Equals("Name"))
                        {
                            item.SetValue(oPeople, "李四");
                        }
                    }

結果如下:

技術分享圖片

c#之反射(Reflection)