In the previous article, we introduced how to obtain the Type
type, which is the foundation of reflection.
In this article, we will use Type
to obtain member information and print the information obtained through reflection to lay a foundation for subsequent reflection operations.
1. Getting Type Information
We often encounter the terms functions and methods, and many people mix them up.
A method is in the form of public void Test(){}
;
A function refers to any code block that can be called using a specific name, such as properties, fields, methods, delegates, events, etc.;
As long as a code block can be called (used) by a specific name, it is a function; while a method is a code block composed of return value, name, parameters, etc.;
To operate reflection, the first step is to obtain the reflection information of a type, and the Type
of the type is closely related to the following various types.
Type | Description |
---|---|
Assembly | Load assemblies, read assembly information, get types, etc. |
Module | Access one or more modules in an assembly |
PropertyInfo | Property information of a type |
FieldInfo | Field information of a type |
ConstructorInfo | Constructor information of a type |
MethodInfo | Methods of a type |
ParameterInfo | Parameters of a constructor or method |
EventInfo | Events of a type |
MemberInfo | Member information, which inherits all types except for Assembly and Module |
1.1 Base Classes and Interfaces of Types
1.1.1 Base Class
In C#, a type can only inherit from one type (base type). Using the instance's Type.BaseType
property, you can get the base type of this type.
Type type = typeof(MyClass);
Type baseType = type.BaseType;
1.1.2 Getting Implemented Interfaces
GetInterface()
and GetInterfaces()
can be used to obtain the interfaces implemented by a type.
Example
Type type = typeof(System.IO.FileStream);
Type[] list = type.GetInterfaces();
foreach (var item in list)
Console.WriteLine(item.Name);
Output
IDisposable
IAsyncDisposable
1.1.3 Getting Generic Interfaces
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);
Output
IList`1
***************
IList`1
ICollection`1
IEnumerable`1
IEnumerable
IList
ICollection
IReadOnlyList`1
IReadOnlyCollection`1
Note that if you want to get the interface Type
by name, you need to use the name of the generic type, such as IList
1`.
1.2 Getting Property and Field Members
1.2.1 Constructors
A type must have a constructor, and even if you do not write a constructor, C# will generate a default constructor at compile time.
GetConstructor()
or GetConstructors()
can obtain the constructor of type ConstructorInfo
;
ConstructorInfo
's GetParameter()
or GetParameters()
can obtain information about the parameters of the constructor;
Create a class
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);
}
}
Output
.ctor | False | True
.ctor | False | True
a | System.Int32 |
The results above indicate that only public constructors can be retrieved;
For more information on using ConstructorInfo
, you can refer here https://docs.microsoft.com/en-us/dotnet/api/system.reflection.constructorinfo?view=netcore-3.1
1.2.2 Properties
You can use GetPropertie()
or GetProperties()
to obtain one or more properties of the type.
Type type = typeof(Type);
PropertyInfo[] list = type.GetProperties();
foreach (var item in list)
Console.WriteLine(item.Name + " | " + item.PropertyType);
Output
IsInterface | System.Boolean
MemberType | System.Reflection.MemberTypes
Namespace | System.String
AssemblyQualifiedName | System.String
FullName | System.String
Assembly | System.Reflection.Assembly
Module | System.Reflection.M
1.2.3 Fields
You can use GetField()
or GetFields()
to obtain one or more fields of the type.
Type type = typeof(Type);
FieldInfo[] list = type.GetFields();
foreach (var item in list)
Console.WriteLine(item.Name + " | " + item.FieldType + " | " + item.IsPublic);
Output
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
Here is a question, are all the retrieved fields public?
Are the fields inside Type
all public, or can reflection only retrieve public fields of the type?
Let's verify this through an experiment.
Create a class
public class MyClass
{
public string A { get; set; }
// non-public property, generally not written like this
private string B { get; set; }
public string C;
protected string D;
internal string E;
private string G;
}</code></pre>
Print
Type type = typeof(MyClass);
PropertyInfo[] listA = type.GetProperties();
// Properties do not have item.IsPublic etc.
foreach (var item in listA)
Console.WriteLine(item.Name + " | " + item.PropertyType);
Console.WriteLine("**************");
IEnumerable<PropertyInfo> listB = 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("**************");
IEnumerable<FieldInfo> listD = type.GetRuntimeFields();
foreach (var item in listD)
Console.WriteLine(item.Name + " | " + item.FieldType + " | " + item.IsPrivate + " | " + item.IsPublic);</code></pre>
Output
A | System.String
**************
A | System.String
B | System.String
**************
C | System.String | False | True
**************
k__BackingField | System.String | True | False
k__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()
and GetFields()
can only retrieve public properties/fields;
GetRuntimeProperties()
and GetRuntimeFields()
can retrieve all properties/fields;
Another important point is that GetRuntimeFields()
retrieves <A>k__BackingField
and <B>k__BackingField
because properties like get;set;
automatically generate backing fields in C#.
1.2.4 Methods
You can use GetMethod()
or GetMethods()
to obtain the MethodInfo
of the type, which represents method information;
MethodInfo
is very similar to ConstructorInfo
, as shown in the example below.
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("***********");
}
Output
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 |
... ...
Reference documentation: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodinfo?view=netcore-3.1
1.2.5 Events
You can use GetEvent()
or GetEvents()
to get the list of events of the type, returning EventInfo
/ EventInfo[]
.
Create a type
public class MyClass
{
public delegate void Test(int a,int b);
public event Test TestHandler;
}
Print
Type type = typeof(MyClass);
EventInfo[] list = type.GetEvents();
foreach (var item in list)
{
Console.WriteLine(item.Name + " | " + item.EventHandlerType);
}
Output
TestHandler | Mytest.MyClass+Test
1.2.6 Members
Use GetMember()
or GetMembers()
to retrieve the members of a type, returning MemberInfo
/ MemberInfo[]
types.
In simple terms, this is an indiscriminate collection of the aforementioned constructors, properties, fields, etc.
Create a type
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()
{
}
}</code></pre>
Print
Type type = typeof(MyClass);
MemberInfo[] list = type.GetMembers();
foreach (var item in list)
{
Console.WriteLine(item.Name + " | " + item.MemberType);
}
Output
add_TestHandler | Method
remove_TestHandler | Method
TestMetod | Method
GetType | Method
ToString | Method
Equals | Method
GetHashCode | Method
.ctor | Constructor
.ctor | Constructor
TestHandler | Event
Test | NestedType
This article is authorized for publication by the "NCC Open Source Community" subscription account.
文章评论