当前位置:网站首页>C Advanced Learning -- Reflection
C Advanced Learning -- Reflection
2022-06-23 06:35:00 【Ambassador Tengyun】
One . The definition of reflection
The ability to review metadata and gather information about its types .
Two . Basic concepts
(1)Assembly: Define and load assemblies , Load all modules in the assembly and find a type from this assembly and create an instance of that type .
(2)Module: Get the assembly containing the module and the classes in the module , You can also get all global methods defined on the module or other specific non global methods .
(3)ConstructorInfo: Gets the name of the constructor 、 Parameters 、 Access modifier ( Such as pulic or private) And implementation details ( Such as abstract or virtual) etc. .
(4)MethodInfo(GetMethod/GetMethods): Get the name of the method 、 Return type 、 Parameters 、 Access modifier ( Such as pulic or private) And implementation details ( Such as abstract or virtual) etc. .
(5)FiedInfo(GetField/GetFields): Gets the name of the field 、 Access modifier ( Such as public or private) And implementation details ( Such as static) etc. , And get or set the field value .
(6)EventInfo(GetEvent/GetEvents): Gets the name of the event 、 Event handler data type 、 Custom properties 、 Declaration type, reflection type, etc , Add or remove event handlers .
(7)PropertyInfo(GetProperty/GetProperties): Gets the name of the property 、 data type 、 Declaration type 、 Reflection type and read-only or writable state, etc , Gets or sets the property value .
(8)ParameterInfo: Get the name of the parameter 、 data type 、 Input parameter or output parameter , And the position of the parameter in the method signature .
(9)MemberInfo(GetMember/GetMembers): Get field 、 event 、 Attributes and so on
3、 ... and . Reflex action
Before demonstrating the effect of reflection , Let's first define the following entity classes , Suppose that the entity class is under a third-party class library , The library name is “TestClass”, Class called "Person"
public class Person
{
private int id;
public int Id { get => id; set => id = value; }
public string Name { set; get; }
public string Phone { get; set; }
public Person()
{
}
public Person(string a, int b)
{
this.Name = a;
this.Phone = b.ToString();
}
public Person(int id, string name, string phone)
{
this.Id = id;
this.Name = name;
this.Phone = phone;
}
public string getName()
{
return this.Name;
}
public string getName1(string str)
{
return str;
}
public string getPhone()
{
return this.Phone;
}
public string getPhone(string str)
{
return this.Phone+str;
}
public string getPhone(string str,int num)
{
return this.Phone + str+num;
}
private void privateMethod(string a)
{
Console.WriteLine(" This is a private method , The parameter passed in is :"+a);
}
}1. Create an object without parameters
Create objects without maturity , The essence is to call a parameterless constructor , The specific implementation is as follows
/// <summary>
/// Create an object without parameters
/// </summary>
/// <returns></returns>
private static Person CreateWithoutParms()
{
Assembly assembly = Assembly.Load("TestClass");// Load assembly
Type type = assembly.GetType("TestClass.Person");// Get class name ( Take the namespace with you )
object o = Activator.CreateInstance(type);// establish Person Entity , No arguments structure
Person person = o as Person;
return person;
}Call in console
Person person = CreateWithoutParms();
person.Name = " Zhang San ";
Console.WriteLine("person.Name:"+ person.Name);Successfully called, created Person, And called Person Is a parameter - free construction method
2. Create an object with parameters
Create objects with maturity , The essence is to call the constructor with parameters , The specific implementation is as follows
/// <summary>
/// Create an object with parameters
/// </summary>
/// <returns></returns>
private static Person CreateWithParms()
{
Assembly assembly = Assembly.Load("TestClass");// Load assembly
Type type = assembly.GetType("TestClass.Person");// Get class name ( Take the namespace with you )
object o = Activator.CreateInstance(type, new object[] {"a",666 });// establish Person Entity , There are parametric structures
Person person = o as Person;
return person;
}Call in console
Person person = CreateWithParms();
Console.WriteLine("person.Name:"+person.Name+ " person.Phone:" + person.Phone);Successfully called, created Person, And use the construction with parameters to assign values to attributes directly
#### explain : If the constructor is private , When you create an instance , take CreateInstance Medium nonPublic Parameter set to true, You can use the private constructor to create an instance
object o = Activator.CreateInstance(type,true);
3. Call the public method
Using reflection to call methods of third-party classes , You can get the corresponding object through reflection , Use the resulting object to execute methods in the object , But here , Mainly through reflection , Directly call methods in third-party classes , The specific implementation is as follows
/// <summary>
/// Call a method with parameters ( No overload )
/// </summary>
/// <returns></returns>
private static string CallFunction()
{
Assembly assembly= Assembly.Load("TestClass");
Type type = assembly.GetType("TestClass.Person");
object o = Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod("getName1");
string result=methodInfo.Invoke(o, new object[] { " This is the incoming parameter " }).ToString();
return result;
}Call in console
string rsult = CallFunction();
Console.WriteLine(rsult);Here we see , Successfully called with reflection getName1 Method , It should be noted that ,getName1 Method has no overload , If you need to call methods with overloads , You need to use the following method , Here we assume that we need to call getPhone(string str,int num) Method
private static string CallFunctionWithOverload()
{
Assembly assembly = Assembly.Load("TestClass");
Type type = assembly.GetType("TestClass.Person");
object o = Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod("getPhone", new Type[] { typeof(string), typeof(int) });// In this case, you need to pass an array of parameter types to GetMethod Method
string result=methodInfo.Invoke(o, new object[] { " This is incoming String Parameters ", 666 }).ToString();
return result;
}Call in console
string rsult = CallFunctionWithOverload();
Console.WriteLine(rsult);Through the above example , We can see , The key to calling overloaded and unloaded methods , Is in the GetMethod Whether to pass the type of the parameter in .
Let's write a comprehensive example , call Person All methods in class , And output the result , If the parameter type is String, The default is "AAA", If the parameter type is Int, The default is 666, The implementation method is as follows :
private static void CallAllFunction()
{
Assembly assembly = Assembly.Load("TestClass");
Type type = assembly.GetType("TestClass.Person");
object o = Activator.CreateInstance(type);
foreach (MethodInfo methodInfoItem in type.GetMethods())
{
Console.WriteLine(" perform "+ methodInfoItem.Name+ " Method ");
List<object> objectList = new List<object>();
foreach (ParameterInfo parameterInfoItem in methodInfoItem.GetParameters())
{
if (parameterInfoItem.ParameterType == typeof(String))
{
objectList.Add("AAA");
}
else if (parameterInfoItem.ParameterType == typeof(int))
{
objectList.Add(666);
}
}
try// Use here try...catch... It is to simplify the problem of processing the program error caused by attribute acquisition failure
{
string result = methodInfoItem.Invoke(o, objectList.ToArray()).ToString();
Console.WriteLine(" The result is :" + result);
}
catch
{
}
}
}After calling, the returned result is as follows :
Here we see ,Person The methods in have been fully implemented , Including all the systems and methods
4. Call private method
/// <summary>
/// Call private method
/// </summary>
private static void CallPrivateFunction()
{
Assembly assembly = Assembly.Load("TestClass");
Type type = assembly.GetType("TestClass.Person");
object o = Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod("privateMethod", BindingFlags.Instance | BindingFlags.NonPublic);
methodInfo.Invoke(o, new object[] { " Zhang San "});
}Through the above example , It's not hard to see , The difference between calling a public method and a private method is calling type Of GetMethod When the method is used , Whether to set up "BindingFlags.Instance | BindingFlags.NonPublic"
5. Get and manipulate properties
/// <summary>
/// Get and manipulate properties
/// </summary>
/// <param name="propertyName"></param>
/// <param name="propertyValue"></param>
private static void getAndSetProperity(string propertyName,string propertyValue)
{
//1. Create by reflection Person Entity
Assembly assembly = Assembly.Load("TestClass");
Type type = assembly.GetType("TestClass.Person");
object o = Activator.CreateInstance(type, new object[] { " Zhang San ", 131000000 });
PropertyInfo propertyInfo=type.GetProperty(propertyName);
Console.WriteLine(" Before the change Phone:"+ propertyInfo.GetValue(o));// Get attribute value
propertyInfo.SetValue(o, propertyValue);// Setting property values
Console.WriteLine(" After modification Phone:" + propertyInfo.GetValue(o));
}Through the above example , You can find , The key methods to get and set properties are respectively GetValue And SetValue, The key input parameter is the entity class obtained by reflection
6. Getting and manipulating fields
/// <summary>
/// Getting and manipulating fields
/// </summary>
/// <param name="fieldName"></param>
/// <param name="fieldValue"></param>
private static void getAndSetField(string fieldName, int fieldValue)
{
Assembly assembly = Assembly.Load("TestClass");
Type type = assembly.GetType("TestClass.Person");
object o = Activator.CreateInstance(type, new object[] {1, " Zhang San ", "131000000" });
FieldInfo fieldInfo = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
Console.WriteLine(" Before the change id"+ fieldInfo.GetValue(o));
fieldInfo.SetValue(o, fieldValue);
Console.WriteLine(" After modification id" + fieldInfo.GetValue(o));
}The method of setting and operating fields is basically the same as that of setting and operating properties , It should be noted that , In use type Of GetField When the method is used , If you get or set a private field , You need to set the accessible properties of the method , The setting in this example is "BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance"
Next , We continue to study the role of reflection in generics , Before further study , Let's first define the following generic class , Just like the above entity classes , Suppose that the generic class is under a third-party class library , The library name is “TestClass”, Class called "GenericClass"
public class GenericClass<X,Y,Z>
{
public X xxx{ set; get; }
public Y yyy { set; get; }
public Z zzz { set; get; }
public void PrintParm<A,B,C>(A a, B b, C c)
{
Console.WriteLine("A The type of " + a.GetType().Name + ", The value is " + a.ToString());
Console.WriteLine("B The type of " + b.GetType().Name + ", The value is " + b.ToString());
Console.WriteLine("C The type of " + c.GetType().Name + ", The value is " + c.ToString());
}
}7. Create a generic class and call
/// <summary>
/// Call methods in generic classes
/// </summary>
private static void GenericWithParms()
{
Assembly assembly = Assembly.Load("TestClass");
Type type = assembly.GetType("TestClass.GenericClass`3");
type= type.MakeGenericType(new Type[] { typeof(string),typeof(int),typeof(DateTime)});
object o = Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod("PrintParm");
methodInfo = methodInfo.MakeGenericMethod(new Type[] { typeof(string), typeof(int), typeof(DateTime) });
methodInfo.Invoke(o, new object[] {" Zhang San ",666,DateTime.Now});
}For the above code , Make the following points :
Only when creating generic classes , That's what you need to do , The number is the total number of generic class parameters
Before creating generic entities , To pass the type Of MakeGenericType Method , Set the type of parameter passed in
Just like creating generic classes , Before calling generic methods , You also need to set the parameter types of generic methods
4). If you call a normal method in a generic class , There is no need to set the parameter types of generic methods , conversely , If you call a generic method in a normal class , There is no need to set the number of generic class parameters , There is no need to set the parameter type
thus , The common ways of reflection are explained ...
Last , In fact, all data tests can be Cloud server Conduct , You can see that Tencent cloud Services related to , The server you bought as test data is very good , At least 38 A year
边栏推荐
- 如何查看本机IP
- minio单节点部署 minio分布式部署 傻瓜式部署过程 (一)
- Day_ 09 smart health project - mobile terminal development - Mobile quick login and permission control
- js创建数组(元素都是对象)
- Design scheme of Small PLC based on t5l1
- Day_ 03 smart communication health project - appointment management - inspection team management
- 把CSMA/CD、Token Bus、Token Ring说清楚
- Qt使用多线程编译项目的方法
- Tencent security 2021 report white paper collection (download attached)
- Word pattern for leetcode topic analysis
猜你喜欢

Vs+qt project transferred to QT Creator
Link of Baidu URL Parameters? Recherche sur le chiffrement et le décryptage des paramètres d'URL (exemple de Code)

【Leetcode】431. Encode n-ary tree to binary tree (difficult)
![[cocos2d-x] custom ring menu](/img/fd/c18c39ae738f6c1d2b76b6c54dc654.png)
[cocos2d-x] custom ring menu

sklearn sklearn中classification_report&精确度/召回率/F1值

程序员的真实想法 | 每日趣闻

图解 Google V8 # 18 :异步编程(一):V8是如何实现微任务的?

How to maintain secure encryption of email communication with FDA?

Day_ 01 smart communication health project - project overview and environmental construction

How to query fields separated by commas in MySQL as query criteria - find_ in_ Set() function
随机推荐
【Leetcode】431. Encode n-ary tree to binary tree (difficult)
机器学习3-岭回归,Lasso,变量选择技术
Pyinstaller package exe setting icon is not displayed
The central network and Information Technology Commission issued the National Informatization Plan for the 14th five year plan, and the network security market entered a period of rapid growth
Day_ 10 smart health project - permission control, graphic report
【接口自动化】软件测试涨薪核心技能、让薪资涨幅200%
Day_ 09 smart health project - mobile terminal development - Mobile quick login and permission control
Xray linkage crawlergo automatic scanning pit climbing record
Given a node of a binary tree, return the successor node of the node
Leetcode topic resolution valid anagram
同步开关电源降低EMI布局 dv/dt di/dt
Home address exchange
What is a PDCA cycle? How to integrate PDCA cycle and OKR
数值计算方法 Chapter7. 计算矩阵的特征值和特征向量
【已解决】“The Unity environment took too long to respond. Make sure that :\n“
如何查看本机IP
Day_ 04 smart health project - appointment management - package management
Find the number of nodes in the widest layer of a binary tree
Leetcode topic resolution valid Sudoku
Possible pits in mongodb project