上一篇文章中,介紹如何獲取 Type 類型,Type 類型是反射的基礎。html
本篇文章中,將使用 Type 去獲取成員信息,經過打印出反射獲取到的信息,爲後續操做反射打好基礎。api
目錄ide
咱們經常能夠看到 函數、方法這兩個詞,不少人對此進行了混用。函數
方法,就是 public void Test(){}
這樣的形式;spa
函數,指具備肯定命名的、而且能夠經過名稱調用的代碼,屬性、字段、方法、委託、事件等;code
只要可以經過肯定的名稱調用(使用)的代碼塊,就是函數;而方法就是 返回值、名稱、參數等組成的代碼塊;htm
要操做反射,首先要獲取到 類型 的反射信息,而類型的 Type ,與如下多種類型密切相關。blog
類型 | 說明 |
---|---|
Assembly | 加載程序集、讀取程序集信息、獲取類型等 |
Module | 訪問程序集中的一個或多個模塊 |
PropertyInfo | 類型的屬性信息 |
FieldInfo | 類型的字段信息 |
ConstructorInfo | 類型的構造函數信息 |
MethodInfo | 類型的方法 |
ParameterInfo | 構造函數或方法的參數 |
EventInfo | 類型的事件 |
MemberInfo | 成員信息,集成以上除 Assembly、Module 外全部的類型 |
C# 中,一個類型只能繼承一個類型(基類型),使用實例的 Type.BaseType
屬性,能夠獲取到此類型的基類型。繼承
Type type = typeof(MyClass); Type baseType = type.BaseType;
GetInterface()
和 GetInterfaces()
能夠獲取類型實現的接口。接口
示例
Type type = typeof(System.IO.FileStream); Type[] list = type.GetInterfaces(); foreach (var item in list) Console.WriteLine(item.Name);
輸出
IDisposable IAsyncDisposable
Type type = typeof(List<>); Type one = type.GetInterface("IList`1"); Console.WriteLine(one.Name); Console.WriteLine("***************"); Type[] list = type.GetInterfaces(); foreach (var item in list) Console.WriteLine(item.Name);
輸出
IList`1 *************** IList`1 ICollection`1 IEnumerable`1 IEnumerable IList ICollection IReadOnlyList`1 IReadOnlyCollection`1
注意的是,若是要經過名稱獲取接口 Type ,須要使用 泛型類別的名稱,例如 IList
1`。
一個類型最少不了的就是構造函數,即便沒有編寫構造函數,C# 編譯時也會生成默認的構造函數。
GetConstructor()
或 GetConstructors()
能夠獲取構造函數 ConstructorInfo
類型;
ConstructorInfo
的 GetParameter()
或 GetParameters()
能夠獲取構造函數的參數信息;
建立一個類
public class MyClass { static MyClass() { } public MyClass() { } private MyClass(string a) { } public MyClass(int a) { } }
打印
Type type = typeof(MyClass); ConstructorInfo[] list = type.GetConstructors(); foreach (var item in list) { Console.WriteLine(item.Name + " | " + item.IsStatic + " | " + item.IsPublic); ParameterInfo[] parms = item.GetParameters(); foreach (var itemNode in parms) { Console.WriteLine(itemNode.Name + " | " + itemNode.ParameterType + " | " + itemNode.DefaultValue); } }
輸出
.ctor | False | True .ctor | False | True a | System.Int32 |
上面結果說明了,只能獲取 Public 的構造函數;
關於 ConstructorInfo
的使用方法,能夠參考這裏 https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection.constructorinfo?view=netcore-3.1
使用 GetPropertie()
或 GetProperties()
能夠獲取 類型 的一個或多個屬性。
Type type = typeof(Type); PropertyInfo[] list = type.GetProperties(); foreach (var item in list) Console.WriteLine(item.Name + " | " + item.PropertyType);
輸出
IsInterface | System.Boolean MemberType | System.Reflection.MemberTypes Namespace | System.String AssemblyQualifiedName | System.String FullName | System.String Assembly | System.Reflection.Assembly Module | System.Reflection.M
使用 GetField()
或 GetFields()
能夠獲取類型的一個或多個字段。
Type type = typeof(Type); FieldInfo[] list = type.GetFields(); foreach (var item in list) Console.WriteLine(item.Name + " | " + item.FieldType + " | " + item.IsPublic);
輸出
Delimiter | System.Char | True EmptyTypes | System.Type[] | True Missing | System.Object | True FilterAttribute | System.Reflection.MemberFilter | True FilterName | System.Reflection.MemberFilter | True FilterNameIgnoreCase | System.Reflection.MemberFilter | True
這裏有個問題,獲取到的全部字段,都是 Public 的?
究竟是 Type 裏面的字段都是 Public 的,仍是反射只能獲取到類型 Public 字段?
咱們經過實驗驗證一下。
建立一個類
public class MyClass { public string A { get; set; } // 不公開的屬性,通常不會這樣寫 private string B { get; set; } public string C; protected string D; internal string E; private string G; }
打印
Type type = typeof(MyClass); PropertyInfo[] listA = type.GetProperties(); // 屬性沒有 item.IsPublic 等 foreach (var item in listA) Console.WriteLine(item.Name + " | " + item.PropertyType); Console.WriteLine("**************"); IEnumerablelistB = type.GetRuntimeProperties(); foreach (var item in listB) Console.WriteLine(item.Name + " | " + item.PropertyType); Console.WriteLine("**************"); FieldInfo[] listC = type.GetFields(); foreach (var item in listC) Console.WriteLine(item.Name + " | " + item.FieldType + " | " + item.IsPrivate + " | " + item.IsPublic); Console.WriteLine("**************"); IEnumerablelistD = type.GetRuntimeFields(); foreach (var item in listD) Console.WriteLine(item.Name + " | " + item.FieldType + " | " + item.IsPrivate + " | " + item.IsPublic);
輸出
A | System.String ************** A | System.String B | System.String ************** C | System.String | False | True **************k__BackingField | System.String | True | Falsek__BackingField | System.String | True | False C | System.String | False | True D | System.String | False | False E | System.String | False | False G | System.String | True | False
GetProperties()
和 GetFields()
都只能獲取到 public 類型的屬性/字段;
GetRuntimeProperties()
和 GetRuntimeFields()
,可以獲取全部的屬性/字段;
還有一個重要的地方,GetRuntimeFields()
獲取到了 k__BackingField
、k__BackingField
,這是由於 {get;set;}
這樣的屬性,C# 會默認生成一個字段給他。
經過 GetMethod()
或 GetMethods()
能夠獲取到類型的 MethodInfo ,表示方法信息;
MethodInfo
跟 ConstructorInfo
很是類似,示例以下
Type type = typeof(System.IO.File); MethodInfo[] list = type.GetMethods(); foreach (var item in list) { Console.WriteLine(item.Name + " | " + item.IsStatic + " | " + item.IsPublic); ParameterInfo[] parms = item.GetParameters(); foreach (var itemNode in parms) { Console.WriteLine(itemNode.Name + " | " + itemNode.ParameterType + " | " + itemNode.DefaultValue); } Console.WriteLine("***********"); }
輸出
OpenText | True | True path | System.String | *********** CreateText | True | True path | System.String | *********** AppendText | True | True path | System.String | *********** Copy | True | True sourceFileName | System.String | destFileName | System.String | ... ...
參考資料地址:https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection.methodinfo?view=netcore-3.1
使用 GetEvent()
或 GetEvents()
能夠獲取類型的事件列表,返回 EventInfo
/ EventInfo[]
類型。
建立一個類型
public class MyClass { public delegate void Test(int a,int b); public event Test TestHandler; }
打印
Type type = typeof(MyClass); EventInfo[] list = type.GetEvents(); foreach (var item in list) { Console.WriteLine(item.Name + " | " + item.EventHandlerType); }
輸出
TestHandler | Mytest.MyClass+Test
使用 GetMember()
或 GetMembers()
獲取類型的成員,返回 MemberInfo
/ MemberInfo[]
類型。
簡單來講,就是以上構造函數、屬性、字段等的無差異集合體。
建立一個類型
public class MyClass { public delegate void Test(int a, int b); public event Test TestHandler; public MyClass(int a) { } public MyClass(int a, int b) { } public void TestMetod() { } }
打印
Type type = typeof(MyClass); MemberInfo[] list = type.GetMembers(); foreach (var item in list) { Console.WriteLine(item.Name + " | " + item.MemberType); }
輸出
add_TestHandler | Method remove_TestHandler | Method TestMetod | Method GetType | Method ToString | Method Equals | Method GetHashCode | Method .ctor | Constructor .ctor | Constructor TestHandler | Event Test | NestedType
此文僅受權《NCC 開源社區》訂閱號發佈