C# 反射(Reflection)
阿新 • • 發佈:2018-02-17
message console 反射 .html sys getmethod png source 文件
什麽是反射
發射是 .net framework 提供的一個幫助類庫,用於讀取和使用元數據。
用到的類:System.Reflection,System.Type。System.Type 類對於反射起著核心的作用。 當反射請求加載的類型時,公共語言運行時將為它創建一個 Type。 您可以使用 Type 對象的方法、字段、屬性和嵌套類來查找有關該類型的所有信息。
反射優缺點
優點:
- 1、反射提高了程序的靈活性和擴展性。
- 2、降低耦合性,提高自適應能力。
- 3、它允許程序創建和控制任何類的對象,無需提前硬編碼目標類。
缺點:
- 1、性能問題:使用反射基本上是一種解釋操作,用於字段和方法接入時要遠慢於直接代碼。因此反射機制主要應用在對靈活性和拓展性要求很高的系統框架上,普通程序不建議使用。
- 2、使用反射會模糊程序內部邏輯;程序員希望在源代碼中看到程序的邏輯,反射卻繞過了源代碼的技術,因而會帶來維護的問題,反射代碼比相應的直接代碼更復雜。
反射的用途
- 1、它允許在運行時查看特性(attribute)信息。
- 2、它允許審查集合中的各種類型,以及實例化這些類型。
- 3、它允許延遲綁定的方法和屬性(property)。
- 4、它允許在運行時創建新類型,然後使用這些類型執行一些任務。
- 5、MVC的路由就是反射做的。訪問的Global的時候,會加載一遍dll
查看元數據
1、獲取當前實例的 System.Type 的兩種方式
//使用對象 GetType()方法Rectangle nc = new Rectangle(); Type type = nc.GetType(); //使用 C# typeof 運算符 Type type = typeof(Rectangle);
2、查看類中的成員
MemberInfo[] minfos = type.GetMembers(); foreach (var i in minfos) { Console.WriteLine("成員: {0}", i.Name); }
3、查看類中的構造方法
ConstructorInfo[] ci = type.GetConstructors();foreach (var i in ci) { Console.WriteLine("構造函數: {0}", i.Name); }
4、查看類中的屬性
PropertyInfo[] pis = type.GetProperties(); foreach (var i in pis) { Console.WriteLine("屬性: {0}", i.Name); }
5、查看類中的字段
FieldInfo[] fis = type.GetFields(); foreach (var i in fis) { Console.WriteLine("字段: {0}", i.Name); }
6、用反射生成對象,並調用屬性、方法和字段進行操作
object obj = Activator.CreateInstance(type);// 創建實例 FieldInfo fi = type.GetField("hight");// 取得length字段 fi.SetValue(obj, 5);// 給ID字段賦值 PropertyInfo pi1 = type.GetProperty("length");// 取得length屬性 pi1.SetValue(obj, 10, null);// 給length屬性賦值 PropertyInfo pi2 = type.GetProperty("width");// 取得width屬性 pi2.SetValue(obj, 20, null);// 給width屬性賦值 MethodInfo mi = type.GetMethod("GetVolume");// 取得show方法 mi.Invoke(obj, null);// 調用GetArea方法
7、查看類中的特性、
Object[] attributes = type.GetCustomAttributes(false); foreach (var i in attributes) { DeBugInfo dbi = i as DeBugInfo; if (null != dbi) { Console.WriteLine("Bug no: {0}, Message: {1}", dbi.BugNo, dbi.Message); } }
8、完整代碼
using System; using System.Reflection; namespace ConsoleTest { // 一個自定義特性 BugFix 被賦給類及其成員 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] public class DeBugInfo : System.Attribute { private int bugNo; public string message; public DeBugInfo(int bg) { this.bugNo = bg; } public int BugNo { get { return bugNo; } } public string Message { get { return message; } set { message = value; } } } /// <summary> /// 矩形 /// </summary> [DeBugInfo(45, Message = "Return type mismatch")] [DeBugInfo(49, Message = "Unused variable")] public class Rectangle { public int hight = 0; public double length { get; set; } public double width { get; set; } public Rectangle() { } public Rectangle(double l, double w) { length = l; width = w; } // 計算面積 [DeBugInfo(55, Message = "Return type mismatch")] public void GetArea() { Console.WriteLine("面積: {0}", length * width); } //計算體積 [DeBugInfo(56)] public void GetVolume() { Console.WriteLine("體積: {0}", length * width * hight); } } class ExecuteRectangle { public static void Main12() { //使用對象GetType()方法 //Rectangle nc = new Rectangle(); //Type type = nc.GetType(); //使用 C# typeof 運算符 Type type = typeof(Rectangle); // 獲取 Rectangle 類的所有成員 Console.WriteLine("\n遍歷 Rectangle 類的成員開始---------------"); MemberInfo[] minfos = type.GetMembers(); foreach (var i in minfos) { Console.WriteLine("成員: {0}", i.Name); } Console.WriteLine("-------------------結束-------------------"); // 獲取 Rectangle 類的所有構造函數 Console.WriteLine("\n遍歷 Rectangle 類的構造函數開始-----------"); ConstructorInfo[] ci = type.GetConstructors(); foreach (var i in ci) { Console.WriteLine("構造函數: {0}", i.Name); } Console.WriteLine("-------------------結束-------------------"); // 獲取 Rectangle 類的所有屬性 Console.WriteLine("\n遍歷 Rectangle 類的屬性開始---------------"); PropertyInfo[] pis = type.GetProperties(); foreach (var i in pis) { Console.WriteLine("屬性: {0}", i.Name); } Console.WriteLine("-------------------結束-------------------"); // 獲取 Rectangle 類的所有public字段 Console.WriteLine("\n遍歷 Rectangle 類的字段開始---------------"); FieldInfo[] fis = type.GetFields(); foreach (var i in fis) { Console.WriteLine("字段: {0}", i.Name); } Console.WriteLine("-------------------結束-------------------"); //用反射生成對象,並調用屬性、方法和字段進行操作 Console.WriteLine("\n用反射生成對象,並調用屬性、方法和字段進行操作"); object obj = Activator.CreateInstance(type);// 創建實例 FieldInfo fi = type.GetField("hight");// 取得length字段 fi.SetValue(obj, 5);// 給ID字段賦值 PropertyInfo pi1 = type.GetProperty("length");// 取得length屬性 pi1.SetValue(obj, 10, null);// 給length屬性賦值 PropertyInfo pi2 = type.GetProperty("width");// 取得width屬性 pi2.SetValue(obj, 20, null);// 給width屬性賦值 MethodInfo mi = type.GetMethod("GetVolume");// 取得show方法 mi.Invoke(obj, null);// 調用GetArea方法 Console.WriteLine("-------------------結束-------------------"); // 遍歷 Rectangle 類的特性 Console.WriteLine("\n遍歷 Rectangle 類的特性開始---------------"); Object[] attributes = type.GetCustomAttributes(false); foreach (var i in attributes) { DeBugInfo dbi = i as DeBugInfo; if (null != dbi) { Console.WriteLine("Bug no: {0}, Message: {1}", dbi.BugNo, dbi.Message); } } Console.WriteLine("-------------------結束-------------------"); // 遍歷 Rectangle 類的方法上的特性(此處只遍歷) Console.WriteLine("\n遍歷 Rectangle 類的方法上的特性開始-------"); MethodInfo[] m = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); foreach (var i in m ) { foreach (Attribute a in i.GetCustomAttributes(true)) { DeBugInfo dbi = a as DeBugInfo; if (null != dbi) { Console.WriteLine("Bug no: {0}, for Method: {1}, Message: {2}", dbi.BugNo, i.Name, dbi.Message); } } } Console.WriteLine("-------------------結束-------------------"); Console.ReadLine(); } } }反射的完整代碼
運行結果:
System.Reflection.Assembly類
Assembly類可以獲得程序集的信息,也可以動態的加載程序集,以及在程序集中查找類型信息,並創建該類型的實例。
使用Assembly類可以降低程序集之間的耦合,有利於軟件結構的合理化。
//通過程序集名稱返回Assembly對象 Assembly ass = Assembly.Load("ConsoleTest"); //通過DLL、EXE文件名稱返回Assembly對象 Assembly ass = Assembly.LoadFrom("ConsoleTest.exe"); //通過Assembly獲取程序集中類 Type t = ass.GetType("ConsoleTest.Rectangle"); //參數必須是類的全名 //通過Assembly獲取程序集中所有的類 Type[] types = ass.GetTypes();
相關文章:http://www.runoob.com/csharp/csharp-reflection.html
https://www.cnblogs.com/Kare/p/4601436.html
C# 反射(Reflection)