標籤:
1.前言
以前也寫過幾篇關於反射的部落格(簡單反射機制),但都理解的不是很深刻,現在在做項目中又一次的用到了反射,在此再總結一下,對於反射的理解。
2.什麼是反射?
最近看部落格,才理解了反射無處不在,我們經常用到的VS中的智能提示,就是通過反射擷取到類的屬性,方法等。反射就是動態擷取程式集中的中繼資料來操作類型的。說的通俗一點,反射就是直接調用Bin檔案夾下的.dll來建立對象,調用成員,擺脫了以前通過執行個體化也就是New操作的方法來調用對象的方法。
小結:反射就是直接調用.dll來建立對象,反射讓建立對象的方式發生了變化。
3.什麼是程式集(Assembly)
程式集是.net中的概念,比如.net中的.exe或者.dll檔案都是程式集。可以把其看做是一堆相關的類的打包。比如包含一些資源檔、類型中繼資料等
其中調用Assembly(程式集)的GetTypes()方法可以得到程式集中定義的所有的類型
調用Assembly的GetType(name)方法可以得到Assembly中定義的全名為name的類型資訊
3.Type類介紹
Type類是實現反射的一個重要的類,通過它可以擷取類中所有的資訊包括方法、屬性等,通過它可以設定屬性或者調用方法。
4.重要的類
Assembly:表示一個程式集,它是一個可重用、可自我描述的通用語言執行平台應用程式構造塊。
Type:表示型別宣告:類類型、介面類型、數群組類型、值類型、枚舉類型、型別參數、泛型型別定義,以及開放或封閉構造的泛型型別。
MethodInfo:探索方法的屬性並提供對方法中繼資料的訪問。
PropertyInfo:發現屬性 (Property) 的屬性 (Attribute) 並提供對屬性 (Property) 中繼資料的訪問。
看了,就明白了反射其實就是另外一種機制,另外一種直接通過.dll檔案來動態建立類的對象。
5.Demo
以下是關於這方面知識,自己聯絡的Demo
<span style="font-size:18px;">using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Reflection;using System.Text;using System.Threading.Tasks;namespace ConsoleApplication2{ class Program { static void Main(string[] args) { string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ClassLibrary1.dll"); //動態載入一個程式集 //C:\Users\ZHOU\Desktop\lianxi\ConsoleApplication2\bin\Debug Assembly ass = Assembly.LoadFile("C:/Users/ZHOU/Desktop/lianxi/ConsoleApplication2/bin/Debug/ClassLibrary1.dll"); //擷取程式集中公用的類型,通常指的是public的類 Type[] types = ass.GetExportedTypes(); foreach (Type type in types) { //類的名字 Console.WriteLine(type.Name); //類的全名稱(命名空間.類名) Console.WriteLine(type.FullName); } //可以擷取到所有的類,包括的是私人的類 //Type[] typ= ass.GetTypes(); foreach (Type item in types) { Console.WriteLine(item.Name); } Console.Read(); //使用FileCommon的預設建構函式建立對象 object o = ass.CreateInstance("commom.FileCommon"); Type t = o.GetType(); //使用指定參數的建構函式建立對象 object oo = Activator.CreateInstance(t, "zs", 18); //判斷student類型的對象,是否可以賦給person。類型的引用調換 bool r = typeof(Person).IsAssignableFrom(typeof(Student)); //判斷學生對象是不是某個類的執行個體 Student b=new Student(); Type d=typeof(Student); bool f=d.IsInstanceOfType(b); //判斷是不是某個類的子類 bool z = typeof(Person).IsSubclassOf(typeof(Student)); #region 動態擷取程式集中的屬性 //GetProperties擷取類型中的所有屬性 PropertyInfo[] pis = d.GetProperties(); foreach (PropertyInfo pi in pis) { if (pi.Name == "Name") { //動態給屬性賦值 pi.SetValue(b, "jk", null); pi.GetValue(b); } } #endregion //Type :描述類型的 //methodInfo:描述方法 #region 動態擷取方法 MethodInfo[] mis = d.GetMethods(); foreach (MethodInfo mi in mis) { //擷取子類中的擴充方法 if (mi.IsSpecialName) { } } #endregion //動態調用Student類的SayHi方法 MethodInfo mid = d.GetMethod("Add"); mid.Invoke(d, null); //也可以通過擷取的type類型直接調用 b.Add(); } } interface Person { int Add(); }; class Student : Person { public int Add() { throw new NotImplementedException(); } }}</span>
總結:反射其實就是另外一種建立對象的機制,只不過更靈活而已,關於以上提到的幾個類,MSDN上有詳細的解釋,裡面有很多可以用到的方法,想學習的可以查一下。
淺析C#種的反射