DynamicMethod:更接近IL

简介:

  DynamicMethod类允许在运行时生成和执行方法,而不必生成动态程序集和动态类型来包含该方法。动态方法是生成和执行少量代码的最有效方式。

  动态方法在逻辑上与模块或类型关联。如果与模块关联,动态方法对于该模块在全局范围内有效。如果有足够的权限,动态方法可以跳过实时 (JIT) 可见性检查,访问在该模块中所声明类型的私有数据。可以将动态方法与任何模块关联,无论该模块是否由您创建。

  如果动态方法与类型关联,动态方法可以访问该类型的私有成员。除非动态方法需要访问在同一模块中声明的其他类型的私有数据,否则无需跳过 JIT 可见性检查。可以将动态方法与任何类型关联。

  无需对动态方法及其参数进行命名,但是可以指定名称以协助调试。动态方法或其属性不支持自定义属性。

  尽管动态方法属于 static 方法,但在 .NET Framework 2.0 版中引入的委托绑定宽松规则允许将动态方法绑定到对象,这使得在使用该委托实例调用动态方法时,可以像调用实例方法那样来调用。下面提供的 CreateDelegate(Type,Object) 方法重载示例对此进行了演示。

复制代码
    class Program
    {
        // Declare a delegate type that can be used to execute the completed
        // dynamic method. 
        private delegate int HelloDelegate(string msg, int ret);

        static void Main(string[] args)
        {
            // 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);

        }
    }
复制代码




本文转自齐师傅博客园博客,原文链接:http://www.cnblogs.com/youring2/archive/2012/06/11/2545694.html,如需转载请自行联系原作者

相关文章
|
4月前
CF一个远古时期的计算几何题(正多边形)
CF一个远古时期的计算几何题(正多边形)
13 0
|
6月前
|
算法 编译器
【计算机架构】响应时间和吞吐量 | 相对性能 | 计算 CPU 时间 | 指令技术与 CPI | T=CC/CR, CC=IC*CPI
【计算机架构】响应时间和吞吐量 | 相对性能 | 计算 CPU 时间 | 指令技术与 CPI | T=CC/CR, CC=IC*CPI
304 0
|
12月前
|
算法 数据可视化
计算代码运行时间的 5 种方法
计算代码运行时间的 5 种方法
483 0
|
12月前
|
算法
零基础VB教程022期:数值分解算法技巧
零基础VB教程022期:数值分解算法技巧
|
Java
使用Java实现BMI指数测试
## 前言: 使用Java实现BMI指数测试,根据用户提供的身高 和体重,调用Scanner方法类,通过类名.的方式进行 对象调用,抓取用户数据,再新建一个double函数用 来接收用户的数据,使用print函数打印提示用户输 入身高和体重,使用构造方法的样式进行编写,通过 类名进行传参,方法调用。 使用if与else的嵌套实现分类管理,对最后的结果 进行分类处理。 最后再打印输出结果
332 0
使用Java实现BMI指数测试
|
算法 Python
算法与python:一台每秒计算10亿次的计算机,使用递归法,从宇宙大爆炸计算到现在,能计算到第几个斐波那契数列?
算法与python:一台每秒计算10亿次的计算机,使用递归法,从宇宙大爆炸计算到现在,能计算到第几个斐波那契数列?
186 0
|
存储 自然语言处理 算法
简单的词法设计——DFA模拟程序
简单的词法设计——DFA模拟程序
212 0
简单的词法设计——DFA模拟程序
|
C++
实验 1 C++简单程序设计(1判断素数.2平均值 3.)
要求: (1)VS2010中创建工程和C++源程序文件。 (2)使用C++中的输入输出头文件和main()函数格式。 (3)程序中使用cin和cout实现数据的输入和输出,并在程序中给出必要的用户提示信息。
130 0
MAT之GA:利用GA对一元函数进行优化过程,求x∈(0,10)中y的最大值
MAT之GA:利用GA对一元函数进行优化过程,求x∈(0,10)中y的最大值
MAT之GA:利用GA对一元函数进行优化过程,求x∈(0,10)中y的最大值