C# 运行时替换方法(需要unsafe编译)
1 /* https://stackoverflow.com/questions/7299097/dynamically-replace-the-contents-of-a-c-sharp-method 2 For .NET 4 and above 3 4 "C:\Program Files (x86)\MSBuild\14.0\Bin\csc.exe" /unsafe+ /out:replacemethod.exe replacemethod.cs && start "replacemethod.exe" replacemethod.exe 5 PrintInfo: Version x64 Release 6 7 1. Replace Instance Method Class1.Demo() 8 Demo 9 Replace result: True 10 Foo 11 12 2. Replace Instance Overload of Method Class1.Demo(10) 13 Demo: 10 14 Replace result: True 15 Foo: 10 16 17 3. Replace Static Method Class1.DemoStatic() 18 DemoStatic 19 Replace result: True 20 FooStatic 21 22 Press any key to EXIT... 23 */ 24 25 using System; 26 using System.Reflection; 27 using System.Runtime.CompilerServices; 28 29 class Program { 30 public static void Main(params string[] args){ 31 PrintInfo(); 32 Console.WriteLine(); 33 34 Test(); 35 36 Console.Write("\nPress any key to EXIT..."); 37 Console.ReadKey(true); 38 } 39 40 public static void PrintInfo() { 41 Console.Write("PrintInfo: "); 42 if (IntPtr.Size == 4) { 43 #if DEBUG 44 Console.WriteLine("Version x86 Debug"); 45 #else 46 Console.WriteLine("Version x86 Release"); 47 #endif 48 } else { 49 #if DEBUG 50 Console.WriteLine("Version x64 Debug"); 51 #else 52 Console.WriteLine("Version x64 Release"); 53 #endif 54 } 55 } 56 57 public static void Test() { 58 Console.WriteLine("1. Replace Instance Method Class1.Demo()"); 59 var o = new Class1(); 60 o.Demo(); 61 var r = CSharpUtils.ReplaceMethod(typeof(Class1), "Demo", typeof(Program), "Foo"); 62 Console.WriteLine("Replace result: {0}", r); 63 o.Demo(); 64 65 Console.WriteLine(); 66 67 Console.WriteLine("2. Replace Instance Overload of Method Class1.Demo(10)"); 68 o.Demo(10); 69 r = CSharpUtils.ReplaceMethod(typeof(Class1), "Demo", typeof(Program), "Foo", types:new Type[]{ typeof(int) }); 70 Console.WriteLine("Replace result: {0}" ,r); 71 o.Demo(10); 72 73 Console.WriteLine(); 74 75 Console.WriteLine("3. Replace Static Method Class1.DemoStatic()"); 76 Class1.DemoStatic(); 77 r = CSharpUtils.ReplaceMethod(typeof(Class1), "DemoStatic", typeof(Program), "FooStatic", BindingFlags.Static|BindingFlags.NonPublic|BindingFlags.Public); 78 Console.WriteLine("Replace result: {0}" ,r); 79 Class1.DemoStatic(); 80 } 81 82 private void Foo() { 83 Console.WriteLine("Foo"); 84 } 85 86 private void Foo(int d) { 87 Console.WriteLine("Foo: {0}", d); 88 } 89 90 private static void FooStatic() { 91 Console.WriteLine("FooStatic"); 92 } 93 } 94 95 96 class Class1 { 97 public void Demo() { 98 Console.WriteLine("Demo"); 99 } 100 101 public void Demo(int d) { 102 Console.WriteLine("Demo: {0}", d); 103 } 104 105 public static void DemoStatic() { 106 Console.WriteLine("DemoStatic"); 107 } 108 } 109 110 111 public static class CSharpUtils { 112 public static bool ReplaceMethod(Type targetType, string targetMethod, Type injectType, string injectMethod, BindingFlags bindingAttr = BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public, Binder binder = null, CallingConventions callConvention = CallingConventions.Any, Type[] types = null, ParameterModifier[] modifiers = null) { 113 if (types == null) { 114 types = Type.EmptyTypes; 115 } 116 MethodInfo tarMethod = targetType.GetMethod(targetMethod, bindingAttr, binder, callConvention, types, modifiers); 117 MethodInfo injMethod = injectType.GetMethod(injectMethod, bindingAttr, binder, callConvention, types, modifiers); 118 if (tarMethod == null || injMethod == null) { 119 return false; 120 } 121 RuntimeHelpers.PrepareMethod(tarMethod.MethodHandle); 122 RuntimeHelpers.PrepareMethod(injMethod.MethodHandle); 123 unsafe { 124 if (IntPtr.Size == 4) { 125 int* tar = (int*)tarMethod.MethodHandle.Value.ToPointer() + 2; 126 int* inj = (int*)injMethod.MethodHandle.Value.ToPointer() + 2; 127 *tar = *inj; 128 } else { 129 long* tar = (long*)tarMethod.MethodHandle.Value.ToPointer() + 1; 130 long* inj = (long*)injMethod.MethodHandle.Value.ToPointer() + 1; 131 *tar = *inj; 132 } 133 } 134 return true; 135 } 136 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构