(0) exportieren Drucken
Alle erweitern

DynamicMethod-Klasse

Hinweis: Diese Klasse ist neu in .NET Framework, Version 2.0.

Definiert eine dynamische Methode und stellt diese dar. Diese Klasse kann nicht geerbt werden.

Namespace: System.Reflection.Emit
Assembly: mscorlib (in 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

Sie können mit der DynamicMethod-Klasse eine Methode zur Laufzeit generieren und ausführen, ohne eine dynamische Assembly oder einen dynamischen Typ erstellen zu müssen, die bzw. der die Methode enthält. Dynamische Methoden sind die rationellste Möglichkeit, kleine Codemengen zu generieren und auszuführen.

Eine dynamische Methode ist einem Modul oder einem Typ logisch zugeordnet. Wenn es einem Modul zugeordnet ist, ist die dynamische Methode für dieses Modul global. Mit ausreichenden Berechtigungen kann eine dynamische Methode Just-In-Time (JIT)-Sichtbarkeitsprüfungen überspringen und auf die privaten Daten der in dem Modul deklarierten Typen zugreifen. Sie können jedem Modul eine dynamische Methode zuordnen, egal ob Sie das Modul erstellt haben.

Wenn einem Typ die dynamische Methode zugeordnet wird, hat sie Zugriff auf die privaten Member des Typs. Die JIT-Sichtbarkeitsprüfungen müssen nur übersprungen werden, wenn die dynamische Methode auf private Daten anderer in demselben Modul deklarierter Typen zugreifen muss. Sie können jedem Typ eine dynamische Methode zuordnen.

In der folgenden Tabelle wird gezeigt, auf welche Member von Typen in einem Modul eine dynamische Methode mit oder ohne JIT-Sichtbarkeitsprüfungen zugreifen kann, die dem Modul oder einem Typ in dem Modul zugeordnet ist.

 

Dem Modul zugeordnet

Dem Typ zugeordnet

JIT-Sichtbarkeitsprüfungen

Öffentliche und interne Member der öffentlichen, internen und privaten Typen.

Alle Member des zugeordneten Typs. Öffentliche und interne Member aller anderen Typen.

Überspringen von JIT-Sichtbarkeitsprüfungen

Alle Member aller Typen.

Alle Member aller Typen.

Eine dynamische Methode verfügt über die Berechtigungen des Moduls, dem sie zugeordnet ist, oder des Moduls, das den Typ enthält, dem die Methode zugeordnet ist.

Dynamische Methoden und ihre Parameter müssen nicht benannt werden, Sie können aber Namen angeben, um das Debuggen zu vereinfachen. Benutzerdefinierte Attribute werden für dynamische Methoden und ihre Parameter nicht unterstützt.

Obwohl dynamische Methoden static-Methoden sind (Shared-Methoden in Visual Basic), ermöglichen die seit .NET Framework, Version 2.0, weniger strengen Regeln für die Delegatenbindung das Binden einer dynamischen Methode an ein Objekt, sodass sie beim Aufruf durch diese Delegateninstanz wie eine Instanzenmethode funktioniert. Ein Beispiel, in dem dies veranschaulicht wird, finden Sie unter der CreateDelegate(Type,Object)-Methodenüberladung.

Im folgenden Codebeispiel wird eine dynamische Methode erstellt, die zwei Parameter akzeptiert. Im Beispiel wird ein einfacher Funktionsrumpf ausgegeben, der den ersten Parameter an der Konsole ausgibt. Der zweite Parameter wird als der Rückgabewert der Methode verwendet. Im Beispiel wird die Methode durch das Erstellen eines Delegaten vervollständigt, anschließend wird der Delegat mit verschiedenen Parametern aufgerufen, und zum Abschluss wird die dynamische Methode mithilfe der Invoke-Methode aufgerufen.

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

Alle öffentlichen statischen (Shared in Visual Basic) Member dieses Typs sind threadsicher. Bei Instanzmembern ist die Threadsicherheit nicht gewährleistet.

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

.NET Framework unterstützt nicht alle Versionen sämtlicher Plattformen. Eine Liste der unterstützten Versionen finden Sie unter Systemanforderungen.

.NET Framework

Unterstützt in: 2.0
Anzeigen:
© 2014 Microsoft