public delegate String MyMethod(String str); private void GenerateMethod() { Type[] argsType = { typeof(String) }; DynamicMethod dm = new DynamicMethod("MyMethod1", typeof(String), argsType, typeof(Form1).Module);//public string MyMethod1(string s) ILGenerator il = dm.GetILGenerator();//{ il.Emit(OpCodes.Ldstr, "hello:");//string a="hello:"; il.Emit(OpCodes.Ldarg_0);//把参数推到堆栈上 il.Emit(OpCodes.Call, typeof(String).GetMethod("Concat", new Type[] { typeof(String), typeof(String) }));//string.Concat(a,s); il.Emit(OpCodes.Ret);//return string.Concat(a,s);} MyMethod myMethod = (MyMethod)dm.CreateDelegate(typeof(MyMethod)); MessageBox.Show(myMethod("my friends")); } private void GenerateMethodTwo() { DynamicMethod dm = new DynamicMethod("Test", null, new Type[] { typeof(string) }, typeof(string).Module); ILGenerator il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0);//把参数推到堆栈上 MethodInfo call = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }); il.Emit(OpCodes.Call, call);//执行Console.WriteLine方法 il.Emit(OpCodes.Ret);//结束返回 Action<string> test = (Action<string>)dm.CreateDelegate(typeof(Action<string>)); test("henry"); //下面Test1方法和Test完成的方法是一样的,但IL似乎有些不同. //主要体现变量设置,对于变量的位置也会影响指令 dm = new DynamicMethod("Test1", null, new Type[] { typeof(string) }, typeof(string).Module); il = dm.GetILGenerator(); il.DeclareLocal(typeof(string));//定义变量 il.Emit(OpCodes.Ldarg_0);//把参数推到堆栈上 il.Emit(OpCodes.Stloc_0);//把值保存到索引为0的变量里 il.Emit(OpCodes.Ldloc_0);//把索引为0的变量推到堆栈上 call = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }); il.Emit(OpCodes.Call, call);//执行Console.WriteLine方法 il.Emit(OpCodes.Ret); test = (Action<string>)dm.CreateDelegate(typeof(Action<string>)); test("henry"); //对于下面的方法大家自己推一下,其实很简单. //如果看起来有不明白,不防copy到vs.net上然后看指令描述信息:) dm = new DynamicMethod("Test2", null, new Type[] { typeof(string) }, typeof(string).Module); il = dm.GetILGenerator(); il.DeclareLocal(typeof(string));//声明一个string局部变量 il.Emit(OpCodes.Ldstr, "你好 ");//推送一个字符串引用 il.Emit(OpCodes.Ldarg_0);//把索引为0参数推到堆栈上 call = typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }); il.Emit(OpCodes.Call, call); il.Emit(OpCodes.Stloc_0);//得到的值存入局部变量 il.Emit(OpCodes.Ldloc_0);//加载局部变量到堆栈 call = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }); il.Emit(OpCodes.Call, call); il.Emit(OpCodes.Ret);//执行方法 test = (Action<string>)dm.CreateDelegate(typeof(Action<string>)); test("henry"); //Console.Read(); } using System; using System.Reflection; using System.Reflection.Emit; using System.Globalization; public class Test { // Declare a delegate type that can be used to execute the completed // dynamic method. private delegate int HelloDelegate(string msg, int ret); public static void Main() { // Create an array that specifies the types of the parameters // of the dynamic method. This dynamic method has a String // parameter and an Integer parameter. Type[] helloArgs = {typeof(string), typeof(int)}; // Create a dynamic method with the name "Hello", a return type // of Integer, and two parameters whose types are specified by // the array helloArgs. Create the method in the module that // defines the String class. DynamicMethod hello = new DynamicMethod("Hello", typeof(int), helloArgs, typeof(string).Module); // Create an array that specifies the parameter types of the // overload of Console.WriteLine to be used in Hello. Type[] writeStringArgs = {typeof(string)}; // Get the overload of Console.WriteLine that has one // String parameter. MethodInfo writeString = typeof(Console).GetMethod("WriteLine", writeStringArgs); // Get an ILGenerator and emit a body for the dynamic method, // using a stream size larger than the IL that will be // emitted. ILGenerator il = hello.GetILGenerator(256); // Load the first argument, which is a string, onto the stack. il.Emit(OpCodes.Ldarg_0); // Call the overload of Console.WriteLine that prints a string. il.EmitCall(OpCodes.Call, writeString, null); // The Hello method returns the value of the second argument; // to do this, load the onto the stack and return. il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ret); // Display MethodAttributes for the dynamic method, set when // the dynamic method was created. Console.WriteLine("\r\nMethod Attributes: {0}", hello.Attributes); // Display the calling convention of the dynamic method, set when the // dynamic method was created. Console.WriteLine("\r\nCalling convention: {0}", hello.CallingConvention); // Display the declaring type, which is always null for dynamic // methods. if (hello.DeclaringType==null) { Console.WriteLine("\r\nDeclaringType is always null for dynamic methods."); } else { Console.WriteLine("DeclaringType: {0}", hello.DeclaringType); } // Display the default value for InitLocals. if (hello.InitLocals) { Console.Write("\r\nThis method contains verifiable code."); } else { Console.Write("\r\nThis method contains unverifiable code."); } Console.WriteLine(" (InitLocals = {0})", hello.InitLocals); // Display the module specified when the dynamic method was created. Console.WriteLine("\r\nModule: {0}", hello.Module); // Display the name specified when the dynamic method was created. // Note that the name can be blank. Console.WriteLine("\r\nName: {0}", hello.Name); // For dynamic methods, the reflected type is always null. if (hello.ReflectedType==null) { Console.WriteLine("\r\nReflectedType is null."); } else { Console.WriteLine("\r\nReflectedType: {0}", hello.ReflectedType); } if (hello.ReturnParameter==null) { Console.WriteLine("\r\nMethod has no return parameter."); } else { Console.WriteLine("\r\nReturn parameter: {0}", hello.ReturnParameter); } // If the method has no return type, ReturnType is System.Void. Console.WriteLine("\r\nReturn type: {0}", hello.ReturnType); // ReturnTypeCustomAttributes returns an ICustomeAttributeProvider // that can be used to enumerate the custom attributes of the // return value. At present, there is no way to set such custom // attributes, so the list is empty. if (hello.ReturnType == typeof(void)) { Console.WriteLine("The method has no return type."); } else { ICustomAttributeProvider caProvider = hello.ReturnTypeCustomAttributes; object[] returnAttributes = caProvider.GetCustomAttributes(true); if (returnAttributes.Length==0) { Console.WriteLine("\r\nThe return type has no custom attributes."); } else { Console.WriteLine("\r\nThe return type has the following custom attributes:"); foreach( object attr in returnAttributes ) { Console.WriteLine("\t{0}", attr.ToString()); } } } Console.WriteLine("\r\nToString: {0}", hello.ToString()); // Add parameter information to the dynamic method. (This is not // necessary, but can be useful for debugging.) For each parameter, // identified by position, supply the parameter attributes and a // parameter name. ParameterBuilder parameter1 = hello.DefineParameter( 1, ParameterAttributes.In, "message" ); ParameterBuilder parameter2 = hello.DefineParameter( 2, ParameterAttributes.In, "valueToReturn" ); // Display parameter information. ParameterInfo[] parameters = hello.GetParameters(); Console.WriteLine("\r\nParameters: name, type, ParameterAttributes"); foreach( ParameterInfo p in parameters ) { Console.WriteLine("\t{0}, {1}, {2}", p.Name, p.ParameterType, p.Attributes); } // Create a delegate that represents the dynamic method. This // action completes the method, and any further attempts to // change the method will cause an exception. HelloDelegate hi = (HelloDelegate) hello.CreateDelegate(typeof(HelloDelegate)); // Use the delegate to execute the dynamic method. Console.WriteLine("\r\nUse the delegate to execute the dynamic method:"); int retval = hi("\r\nHello, World!", 42); Console.WriteLine("Invoking delegate hi(\"Hello, World!\", 42) returned: " + retval); // Execute it again, with different arguments. retval = hi("\r\nHi, Mom!", 5280); Console.WriteLine("Invoking delegate hi(\"Hi, Mom!\", 5280) returned: " + retval); Console.WriteLine("\r\nUse the Invoke method to execute the dynamic method:"); // Create an array of arguments to use with the Invoke method. object[] invokeArgs = {"\r\nHello, World!", 42}; // Invoke the dynamic method using the arguments. This is much // slower than using the delegate, because you must create an // array to contain the arguments, and value-type arguments // must be boxed. object objRet = hello.Invoke(null, BindingFlags.ExactBinding, null, invokeArgs, new CultureInfo("en-us")); Console.WriteLine("hello.Invoke returned: " + objRet); } } /* This code example produces the following output: Method Attributes: PrivateScope, Public, Static Calling convention: Standard DeclaringType is always null for dynamic methods. This method contains verifiable code. (InitLocals = True) Module: CommonLanguageRuntimeLibrary Name: Hello ReflectedType is null. Method has no return parameter. Return type: System.Int32 The return type has no custom attributes. ToString: Int32 Hello(System.String, Int32) Parameters: name, type, ParameterAttributes message, System.String, In valueToReturn, System.Int32, In Use the delegate to execute the dynamic method: Hello, World! Invoking delegate hi("Hello, World!", 42) returned: 42 Hi, Mom! Invoking delegate hi("Hi, Mom!", 5280) returned: 5280 Use the Invoke method to execute the dynamic method: Hello, World! hello.Invoke returned: 42 */
DynamicMethod 类
最新推荐文章于 2024-08-30 10:12:23 发布