翼度科技»论坛 编程开发 .net 查看内容

探秘C#中的秘密通道:五种引人注目的方法调用内部或私有方法

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
在 C# 中,可以使用不同的方法调用内部或私有方法。下面分别介绍通过反射、MethodInfo.CreateDelegate、表达式(树)、动态方法(call)、动态方法(calli)这五种方法。1. 通过反射方法

使用反射可以访问和调用内部或私有方法。
  1. using System;
  2. using System.Reflection;
  3. public class MyClass
  4. {
  5.     private void MyPrivateMethod()
  6.     {
  7.         Console.WriteLine("调用了私有方法");
  8.     }
  9. }
  10. class Program
  11. {
  12.     static void Main()
  13.     {
  14.         MyClass myObject = new MyClass();
  15.         // 通过反射获取私有方法
  16.         MethodInfo methodInfo = typeof(MyClass).GetMethod("MyPrivateMethod", BindingFlags.NonPublic | BindingFlags.Instance);
  17.         // 调用私有方法
  18.         methodInfo.Invoke(myObject, null);
  19.     }
  20. }
复制代码
2. 使用 MethodInfo.CreateDelegate 方法

通过 MethodInfo.CreateDelegate 方法可以创建委托,然后调用私有方法。
  1. using System;
  2. using System.Reflection;
  3. public class MyClass
  4. {
  5.     private void MyPrivateMethod()
  6.     {
  7.         Console.WriteLine("调用了私有方法");
  8.     }
  9. }
  10. class Program
  11. {
  12.     static void Main()
  13.     {
  14.         MyClass myObject = new MyClass();
  15.         // 通过反射获取私有方法
  16.         MethodInfo methodInfo = typeof(MyClass).GetMethod("MyPrivateMethod", BindingFlags.NonPublic | BindingFlags.Instance);
  17.         // 创建委托
  18.         Action action = (Action)Delegate.CreateDelegate(typeof(Action), myObject, methodInfo);
  19.         // 调用私有方法
  20.         action();
  21.     }
  22. }
复制代码
3. 使用表达式(树)方法

通过表达式(树)可以创建动态方法,然后调用私有方法。
  1. using System;
  2. using System.Linq.Expressions;
  3. public class MyClass
  4. {
  5.     private void MyPrivateMethod()
  6.     {
  7.         Console.WriteLine("调用了私有方法");
  8.     }
  9. }
  10. class Program
  11. {
  12.     static void Main()
  13.     {
  14.         MyClass myObject = new MyClass();
  15.         // 使用表达式创建动态方法
  16.         Action action = CreateDelegate<Action>(myObject, "MyPrivateMethod");
  17.         // 调用私有方法
  18.         action();
  19.     }
  20.     // 使用表达式创建动态方法的通用方法
  21.     static TDelegate CreateDelegate<TDelegate>(object target, string methodName)
  22.     {
  23.         var methodInfo = target.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
  24.         var parameter = Expression.Parameter(typeof(object), "instance");
  25.         var call = Expression.Call(Expression.Convert(parameter, target.GetType()), methodInfo);
  26.         var lambda = Expression.Lambda<TDelegate>(call, parameter);
  27.         return lambda.Compile();
  28.     }
  29. }
复制代码
4. 使用动态方法(call)方法

使用动态方法可以调用私有方法。
  1. using System;
  2. using System.Reflection;
  3. using System.Reflection.Emit;
  4. public class MyClass
  5. {
  6.     private void MyPrivateMethod()
  7.     {
  8.         Console.WriteLine("调用了私有方法");
  9.     }
  10. }
  11. class Program
  12. {
  13.     static void Main()
  14.     {
  15.         MyClass myObject = new MyClass();
  16.         // 使用动态方法调用私有方法
  17.         CallPrivateMethod(myObject, "MyPrivateMethod");
  18.     }
  19.     // 使用动态方法调用私有方法的通用方法
  20.     static void CallPrivateMethod(object target, string methodName)
  21.     {
  22.         var methodInfo = target.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
  23.         // 使用动态方法
  24.         var dynamicMethod = new DynamicMethod("CallMethod", null, new[] { typeof(object) }, target.GetType());
  25.         var ilGenerator = dynamicMethod.GetILGenerator();
  26.         ilGenerator.Emit(OpCodes.Ldarg_0); // 加载第一个参数,即目标实例
  27.         ilGenerator.EmitCall(OpCodes.Call, methodInfo, null); // 调用私有方法
  28.         ilGenerator.Emit(OpCodes.Ret); // 返回
  29.         var action = (Action<object>)dynamicMethod.CreateDelegate(typeof(Action<object>));
  30.         // 调用私有方法
  31.         action(target);
  32.     }
  33. }
复制代码
5. 使用动态方法(calli)方法

使用动态方法(calli)可以调用私有方法。
  1. using System;
  2. using System.Reflection.Emit;
  3. public class MyClass
  4. {
  5.     private void MyPrivateMethod()
  6.     {
  7.         Console.WriteLine("调用了私有方法");
  8.     }
  9. }
  10. class Program
  11. {
  12.     static void Main()
  13.     {
  14.         MyClass myObject = new MyClass();
  15.         // 使用动态方法(calli)调用私有方法
  16.         CallPrivateMethod(myObject, "MyPrivateMethod");
  17.     }
  18.     // 使用动态方法(calli)调用私有方法的通用方法
  19.     static void CallPrivateMethod(object target, string methodName)
  20.     {
  21.         var methodInfo = target.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
  22.         // 使用动态方法(calli)
  23.         var dynamicMethod = new DynamicMethod("CallMethod", typeof(void), new[] { typeof(object) }, target.GetType());
  24.         var ilGenerator = dynamicMethod.GetILGenerator();
  25.         ilGenerator.Emit(OpCodes.Ldarg_0); // 加载第一个参数,即目标实例
  26.         ilGenerator.EmitCalli(OpCodes.Call, methodInfo.CallingConvention, methodInfo.ReturnType, methodInfo.GetParameters().Select(p => p.ParameterType).ToArray(), null); // 调用私有方法
  27.         ilGenerator.Emit(OpCodes.Ret); // 返回
  28.         var action = (Action<object>)dynamicMethod.CreateDelegate(typeof(Action<object>));
  29.         // 调用私有方法
  30.         action(target);
  31.     }
  32. }
复制代码
以上五种方法都可以用于调用内部或私有方法,具体使用哪种方法取决于具体的场景和需求。
 


来源:https://www.cnblogs.com/hanbing81868164/archive/2023/12/10/17892159.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具