DynamicMethod (Clase)

DynamicMethod (Clase)

Nota: esta clase es nueva en la versión 2.0 de .NET Framework.

Define y representa un método dinámico. Esta clase no se puede heredar.

Espacio de nombres: System.Reflection.Emit
Ensamblado: mscorlib (en mscorlib.dll)

[ComVisibleAttribute(true)] 
public sealed class DynamicMethod : MethodInfo
/** @attribute ComVisibleAttribute(true) */ 
public final class DynamicMethod extends MethodInfo
ComVisibleAttribute(true) 
public final class DynamicMethod extends MethodInfo

Puede utilizar la clase DynamicMethod para generar y ejecutar un método en tiempo de ejecución, sin tener que generar un ensamblado dinámico y un tipo dinámico para contener el método. Los métodos dinámicos son la forma más eficaz de generar y ejecutar cantidades pequeñas de código.

Un método dinámico está asociado lógicamente a un módulo o a un tipo. Si está asociado a un módulo, el método dinámico es de hecho global para ese módulo. Con los permisos necesarios, un método dinámico puede omitir las comprobaciones de visibilidad just-in-time (JIT) y el acceso a los datos privados de los tipos declarados en ese módulo. Puede asociar un método dinámico a cualquier módulo, independientemente de si creó o no el módulo.

Si el método dinámico está asociado a un tipo, tiene acceso a los miembros privados del tipo. No hay ninguna necesidad de omitir las comprobaciones de visibilidad JIT, a menos que el método dinámico obtenga acceso a los datos privados de otros tipos declarados en el mismo módulo. Puede asociar un método dinámico a cualquier tipo.

En la tabla siguiente se muestran los miembros de tipos de un módulo que son accesibles a un método dinámico, con y sin comprobaciones de visibilidad JIT, para los métodos dinámicos asociados al módulo o a un tipo del módulo.

 

Asociado a un módulo

Asociado a un tipo

Comprobaciones de visibilidad JIT

Los miembros públicos e internos de tipos públicos, internos y privados.

Todos los miembros del tipo asociado. Los miembros públicos e internos de todos los demás tipos.

Omitir las comprobaciones de visibilidad JIT

Todos los miembros de todos los tipos.

Todos los miembros de todos los tipos.

Un método dinámico tiene los permisos del módulo al que está asociado o del módulo que contiene el tipo al que está asociado.

No es necesario asignar un nombre a los métodos dinámicos y sus parámetros, pero puede especificar nombres para facilitar la depuración. No se admiten atributos personalizados en métodos dinámicos o sus parámetros.

Aunque los métodos dinámicos son métodos static (métodos Shared en Visual Basic), las reglas relajadas para enlaces de delegado incorporadas en la versión 2.0 de .NET Framework permiten el enlace de un método dinámico a un objeto, de manera que se comporte como un método de instancia cuando se realizan llamadas utilizando esa instancia de delegado. Se incluye un ejemplo demostrativo para la sobrecarga del método CreateDelegate(Type,Object).

En el ejemplo de código siguiente se crea un método dinámico que toma dos parámetros. Además, se emite el cuerpo de una función sencilla que imprime el primer parámetro en la consola y se utiliza el segundo parámetro como valor devuelto del método. Asimismo, se finaliza el método creando un delegado, se llama al delegado con diferentes parámetros y, finalmente, se llama al método dinámico usando el método Invoke.

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
 */

System.Object
   System.Reflection.MemberInfo
     System.Reflection.MethodBase
       System.Reflection.MethodInfo
        System.Reflection.Emit.DynamicMethod

Los miembros estáticos públicos (Shared en Visual Basic) de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows 98, Windows 2000 SP4, Windows Millennium, Windows Server 2003, Windows XP Media Center, Windows XP Professional x64, Windows XP SP2, Windows XP Starter Edition

.NET Framework no admite todas las versiones de cada plataforma. Para obtener una lista de las versiones admitidas, vea Requisitos del sistema.

.NET Framework

Compatible con: 2.0

Adiciones de comunidad

AGREGAR
Mostrar:
© 2016 Microsoft