c# emit 实现类的代理
using System; using System.Linq; using System.Reflection; using System.Reflection.Emit; namespace EmitCreateDynamicProxy { class Program { static void Main(string[] args) { var command = Proxy.Of<Command>(); command.Execute(); Console.ReadLine(); } } public class Command { public virtual void Execute() { Console.WriteLine("Hello Kitty!"); } } public class Interceptor { public object Invoke(object @object, string @method, object[] parameters) { Console.WriteLine( string.Format(" before invoke [{0}]...", @method)); var retObj = @object.GetType().GetMethod(@method).Invoke(@object, parameters); Console.WriteLine( string.Format(" after invoke [{0}]...", @method)); return retObj; } } public class Proxy { public static T Of<T>() { string nameOfAssembly = typeof(T).Name + "ProxyAssembly"; string nameOfModule = typeof(T).Name + "ProxyModule"; string nameOfType = typeof(T).Name + "Proxy"; var assemblyName = new AssemblyName(nameOfAssembly); var assembly = AppDomain.CurrentDomain .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); var moduleBuilder = assembly.DefineDynamicModule(nameOfModule); var typeBuilder = moduleBuilder.DefineType( nameOfType, TypeAttributes.Public,typeof(T)); InjectInterceptor<T>(typeBuilder); var t = typeBuilder.CreateType(); return (T)Activator.CreateInstance(t) ; } private static void InjectInterceptor<T>(TypeBuilder typeBuilder) { // ---- define fields ---- var fieldInterceptor = typeBuilder.DefineField( "_interceptor", typeof(Interceptor), FieldAttributes.Private); // ---- define costructors ---- var constructorBuilder = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, null); var ilOfCtor = constructorBuilder.GetILGenerator(); ilOfCtor.Emit(OpCodes.Ldarg_0); ilOfCtor.Emit(OpCodes.Newobj, typeof(Interceptor).GetConstructor(new Type[0])); ilOfCtor.Emit(OpCodes.Stfld, fieldInterceptor); ilOfCtor.Emit(OpCodes.Ret); // ---- define methods ---- var methodsOfType = typeof(T).GetMethods(BindingFlags.Public | BindingFlags.Instance); for (var i = 0; i < methodsOfType.Length; i++) { var method = methodsOfType[i]; var methodParameterTypes = method.GetParameters().Select(p => p.ParameterType).ToArray(); var methodBuilder = typeBuilder.DefineMethod( method.Name, MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard, method.ReturnType, methodParameterTypes); var ilOfMethod = methodBuilder.GetILGenerator(); ilOfMethod.Emit(OpCodes.Ldarg_0); ilOfMethod.Emit(OpCodes.Ldfld, fieldInterceptor); // create instance of T ilOfMethod.Emit(OpCodes.Newobj, typeof(T).GetConstructor(new Type[0])); ilOfMethod.Emit(OpCodes.Ldstr, method.Name); // build the method parameters if (methodParameterTypes == null) { ilOfMethod.Emit(OpCodes.Ldnull); } else { var parameters = ilOfMethod.DeclareLocal(typeof(object[])); ilOfMethod.Emit(OpCodes.Ldc_I4, methodParameterTypes.Length); ilOfMethod.Emit(OpCodes.Newarr, typeof(object)); ilOfMethod.Emit(OpCodes.Stloc, parameters); for (var j = 0; j < methodParameterTypes.Length; j++) { ilOfMethod.Emit(OpCodes.Ldloc, parameters); ilOfMethod.Emit(OpCodes.Ldc_I4, j); ilOfMethod.Emit(OpCodes.Ldarg, j + 1); ilOfMethod.Emit(OpCodes.Stelem_Ref); } ilOfMethod.Emit(OpCodes.Ldloc, parameters); } // call Invoke() method of Interceptor ilOfMethod.Emit(OpCodes.Callvirt, typeof(Interceptor).GetMethod("Invoke")); // pop the stack if return void if (method.ReturnType == typeof(void)) { ilOfMethod.Emit(OpCodes.Pop); } // complete ilOfMethod.Emit(OpCodes.Ret); } } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通