上一篇文章中,介绍如何获取 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 开源社区》订阅号发布