当前位置:网站首页>Reflection principle and application in C #

Reflection principle and application in C #

2022-06-09 02:37:00 God of Luo Xiu

Let's take a look at a picture

 Insert picture description here
Reverse engineering , You can put Dll/Exe Decompile the file ,IL Is a reference to C# The code of the code ,metadata Is a list of data , Record what it contains, not the details of the implementation ;
1. The principle of reflection :
Reflection is System.Reflection Namespace , Can read metadata, And use metadata, It is a help class provided by Microsoft , It is used in all scenarios , And its main function is “ decoupling ”, Reduce reliance on details .

The simple understanding is , When C# When the code is compiled , The classes and methods in the project will be recorded in metadata Inside , And then use it System.reflection Can read metadata Recorded information , Thus, you can get the corresponding type and all class methods according to the instance of the type .

Next is the application , Look at the code below

scene 1
By getting an example of Type, And then use this Type To generate a new instance

namespace ConsoleApp1
{
    
    class Class1
    {
    
        public void Fun(int a, int b)
        {
    
            int res = a + b;
            Console.WriteLine($"Fun res is {
      res}");
        }

        public int val = 10;
    }
    
    static void Main(string[] args)
      {
    
          Class1 class_a = new Class1();
          Type a_type = class_a.GetType();
          dynamic aa = Activator.CreateInstance(a_type); //  Dynamically create a new class instance based on a class type 
          Console.WriteLine(aa.GetType()); //  The output is zero ConsoleApp1.Class1
          Console.WriteLine(aa.val); // 10
      }
 }

scene 2
establish dll Examples in , This is just for convenience , Generate solutions from the above projects , In its bin There will be corresponding in the directory dll file , The code is as follows :

        static void Main(string[] args)
        {
    
        	// The absolute path here , Find your previously generated dll file 
            Assembly assembly = Assembly.LoadFrom("E:/study_file/Pracfile/CStest1/ConsoleApp1/bin/Debug/netcoreapp3.1/ConsoleApp1.dll");
            Type cur_type = assembly.GetType("ConsoleApp1.Class1");
            dynamic cur_obj = Activator.CreateInstance(cur_type);
            Console.WriteLine($"res is : {
      cur_obj.GetType()}"); // res is : ConsoleApp1.Class1
        }

Here, the generation is based on the type obtained , Two examples of generating instances , The following describes how to get the corresponding type methods and their calls . The code is as follows :

namespace ConsoleApp1
{
    
    class Class1
    {
    
        public void Fun(int a, int b)
        {
    
            int res = a + b;
            Console.WriteLine($"a = {
      a} b = {
      b}");
        }

        public void Fun(int a, int b, int c) //  heavy load 
        {
    
            int res = a + b;
            Console.WriteLine($"a = {
      a} b = {
      b} c = {
      c}");
        }

        public int val = 10;
    }
	
	        static void Main(string[] args)
        {
    
            Assembly assembly = Assembly.LoadFrom("E:/study_file/Pracfile/CStest1/ConsoleApp1/bin/Debug/netcoreapp3.1/ConsoleApp1.dll");// The absolute path here , Find your previously generated dll file 
            Type cur_type = assembly.GetType("ConsoleApp1.Class1");
            dynamic cur_obj = Activator.CreateInstance(cur_type);//  Generate instances 
            //  According to the function name , And parameter list Type Type to get the corresponding function , The access is saved in metadata Data information in 
            MethodInfo methodInfo_a = cur_type.GetMethod("Fun",new Type[] {
     typeof(int), typeof(int)}); 
            methodInfo_a?.Invoke(cur_obj, new object[] {
     3, 5 });
            MethodInfo methodInfo_b = cur_type.GetMethod("Fun", new Type[] {
     typeof(int), typeof(int), typeof(int) });
            methodInfo_b?.Invoke(cur_obj, new object[] {
     3, 5, 7 }); //  Call the corresponding function 

        }
}

There are also some commonly used function interfaces , Also simply record

namespace ConsoleApp1
{
    
    class Class1
    {
    
        private void Test()
        {
    
            Console.WriteLine($"this is pricate Test !!!");
        }
        public void Fun(int a, int b)
        {
    
            int res = a + b;
            Console.WriteLine($"a = {
      a} b = {
      b}");
        }

        public void Fun(int a, int b, int c)
        {
    
            int res = a + b;
            Console.WriteLine($"a = {
      a} b = {
      b} c = {
      c}");
        }

        public int val = 10;
    }

 class Program
    {
    
        static void Main(string[] args)
        {
    
            Assembly assembly = Assembly.LoadFrom("E:/study_file/Pracfile/CStest1/ConsoleApp1/bin/Debug/netcoreapp3.1/ConsoleApp1.dll");// The absolute path here , Find your previously generated dll file 
            Type cur_type = assembly.GetType("ConsoleApp1.Class1");
            dynamic cur_obj = Activator.CreateInstance(cur_type);
            // Get a list of all the functions 
            MethodInfo[] methodInfos = cur_type.GetMethods(); 
            foreach(MethodInfo m in methodInfos)
            {
    

            }
            // Get a single function 
            MethodInfo methodInfo_a = cur_type.GetMethod("Fun", new Type[] {
     typeof(int), typeof(int), typeof(int) });
            methodInfo_a?.Invoke(cur_obj, new object[] {
     1,2,3});
            // use  BindingFlags Mark the function range obtained   The range represented here is the non-public function in the instance (private protect internal)
            MethodInfo methodInfo_b = cur_type.GetMethod("Test", BindingFlags.Instance | BindingFlags.NonPublic);
            methodInfo_b?.Invoke(cur_obj, null); // this is pricate Test !!! Private functions can be called directly here , Isn't that amazing 
        }
    }
 }

Reference documents

原网站

版权声明
本文为[God of Luo Xiu]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/160/202206090235421140.html