zoukankan      html  css  js  c++  java
  • 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);
    
            }
        }

    本文摘自MSDN中对DynamicMethod的描述:http://msdn.microsoft.com/zh-cn/library/system.reflection.emit.dynamicmethod%28v=vs.80%29.aspx

  • 相关阅读:
    有个名字叫随便乱记——css3
    CSS3伸缩布局
    路政整理
    GIst
    SVN回滚版本
    你需要知道的CSS3 动画技术
    iScroll框架的使用和修改
    CSS3阴影 box-shadow的使用和技巧总结
    Javascript异步编程的4种方法
    zepto学习零碎
  • 原文地址:https://www.cnblogs.com/youring2/p/2545694.html
Copyright © 2011-2022 走看看