DynamicMethod.CreateDelegate Metoda

Definicja

Kończy metodę dynamiczną i tworzy delegata, którego można użyć do jego wykonania.

Przeciążenia

CreateDelegate(Type)

Kończy metodę dynamiczną i tworzy delegata, którego można użyć do jego wykonania.

CreateDelegate(Type, Object)

Kończy metodę dynamiczną i tworzy delegata, którego można użyć do jego wykonania, określając typ delegata i obiekt, do którego jest powiązany delegat.

CreateDelegate(Type)

Źródło:
DynamicMethod.cs
Źródło:
DynamicMethod.CoreCLR.cs
Źródło:
DynamicMethod.CoreCLR.cs

Kończy metodę dynamiczną i tworzy delegata, którego można użyć do jego wykonania.

public override sealed Delegate CreateDelegate (Type delegateType);
[System.Runtime.InteropServices.ComVisible(true)]
public Delegate CreateDelegate (Type delegateType);
[System.Runtime.InteropServices.ComVisible(true)]
public override sealed Delegate CreateDelegate (Type delegateType);

Parametry

delegateType
Type

Typ delegata, którego podpis jest zgodny z metodą dynamiczną.

Zwraca

Delegat określonego typu, którego można użyć do wykonania metody dynamicznej.

Atrybuty

Wyjątki

Metoda dynamiczna nie ma treści metody.

delegateType ma nieprawidłową liczbę parametrów lub nieprawidłowych typów parametrów.

Przykłady

Poniższy przykład kodu tworzy metodę dynamiczną, która przyjmuje dwa parametry. Przykład emituje prostą treść funkcji, która wyświetla pierwszy parametr w konsoli, a w przykładzie użyto drugiego parametru jako wartości zwracanej metody. Przykład kończy metodę, tworząc delegata, wywołuje delegata z różnymi parametrami, a na koniec wywołuje metodę dynamiczną przy użyciu Invoke metody .

using System;
using System.Reflection;
using System.Reflection.Emit;
using Microsoft.VisualBasic;

public class Test
{
    // Declare a delegate that will be used to execute the completed
    // dynamic method.
    private delegate int HelloInvoker(string msg, int ret);

    public static void Main()
    {
        // Create an array that specifies the types of the parameters
        // of the dynamic method. This method has a string parameter
        // and an int parameter.
        Type[] helloArgs = {typeof(string), typeof(int)};

        // Create a dynamic method with the name "Hello", a return type
        // of int, and two parameters whose types are specified by the
        // array helloArgs. Create the method in the module that
        // defines the Test class.
        DynamicMethod hello = new DynamicMethod("Hello",
            typeof(int),
            helloArgs,
            typeof(Test).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.
        ILGenerator il = hello.GetILGenerator();
        // 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);

        // 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.
        HelloInvoker hi =
            (HelloInvoker) hello.CreateDelegate(typeof(HelloInvoker));

        // Use the delegate to execute the dynamic method. Save and
        // print the return value.
        int retval = hi("\r\nHello, World!", 42);
        Console.WriteLine("Executing delegate hi(\"Hello, World!\", 42) returned {0}",
            retval);

        // Do it again, with different arguments.
        retval = hi("\r\nHi, Mom!", 5280);
        Console.WriteLine("Executing delegate hi(\"Hi, Mom!\", 5280) returned {0}",
            retval);

        // 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 ValueType arguments
        // must be boxed.
        object objRet = hello.Invoke(null, invokeArgs);
        Console.WriteLine("hello.Invoke returned {0}", objRet);
    }
}

Uwagi

CreateDelegate Wywołanie metody lub Invoke metody kończy metodę dynamiczną. Wszelkie dalsze próby zmiany metody dynamicznej, takie jak modyfikowanie definicji parametrów lub emitowanie większej liczby języków pośrednich firmy Microsoft (MSIL), są ignorowane; nie jest zgłaszany żaden wyjątek.

Aby utworzyć treść metody dla metody dynamicznej, gdy masz własny generator MSIL, wywołaj GetDynamicILInfo metodę DynamicILInfo w celu uzyskania obiektu. Jeśli nie masz własnego generatora MSIL, wywołaj GetILGenerator metodę ILGenerator , aby uzyskać obiekt, którego można użyć do wygenerowania treści metody.

Zobacz też

Dotyczy

.NET 9 i inne wersje
Produkt Wersje
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1

CreateDelegate(Type, Object)

Źródło:
DynamicMethod.cs
Źródło:
DynamicMethod.CoreCLR.cs
Źródło:
DynamicMethod.CoreCLR.cs

Kończy metodę dynamiczną i tworzy delegata, którego można użyć do jego wykonania, określając typ delegata i obiekt, do którego jest powiązany delegat.

public override sealed Delegate CreateDelegate (Type delegateType, object? target);
public override sealed Delegate CreateDelegate (Type delegateType, object target);
[System.Runtime.InteropServices.ComVisible(true)]
public Delegate CreateDelegate (Type delegateType, object target);
[System.Runtime.InteropServices.ComVisible(true)]
public override sealed Delegate CreateDelegate (Type delegateType, object target);

Parametry

delegateType
Type

Typ delegata, którego podpis jest zgodny z metodą dynamiczną, minus pierwszy parametr.

target
Object

Obiekt, z którymi jest powiązany delegat. Musi być tego samego typu co pierwszy parametr metody dynamicznej.

Zwraca

Delegat określonego typu, który może służyć do wykonywania metody dynamicznej z określonym obiektem docelowym.

Atrybuty

Wyjątki

Metoda dynamiczna nie ma treści metody.

target nie jest tym samym typem co pierwszy parametr metody dynamicznej i nie można przypisać go do tego typu.

-lub-

delegateType ma nieprawidłową liczbę parametrów lub nieprawidłowych typów parametrów.

Przykłady

Poniższy przykład kodu tworzy delegata, który wiąże się DynamicMethod z wystąpieniem typu, tak aby metoda działa na tym samym wystąpieniu za każdym razem, gdy jest wywoływana.

Przykład kodu definiuje klasę o nazwie z polem prywatnym, klasę o nazwieExample, która pochodzi z pierwszej klasy, typ delegata o nazwie DerivedFromExample , który zwraca i ma parametry typu Example i Int32, oraz typ delegata o nazwie UseLikeInstanceUseLikeStatic , który zwraca Int32Int32 i ma jeden parametr typu Int32.

Przykładowy kod tworzy DynamicMethod element, który zmienia pole prywatne wystąpienia i Example zwraca poprzednią wartość.

Uwaga

Ogólnie rzecz biorąc, zmiana wewnętrznych pól klas nie jest dobrą praktyką kodowania zorientowaną na obiekty.

Przykładowy kod tworzy wystąpienie obiektu Example , a następnie tworzy dwa delegaty. Pierwszy jest typu UseLikeStatic, który ma te same parametry co metoda dynamiczna. Drugi jest typu UseLikeInstance, który nie ma pierwszego parametru (typu Example). Ten delegat jest tworzony przy użyciu CreateDelegate(Type, Object) przeciążenia metody; drugi parametr przeciążenia tej metody jest wystąpieniem Example, w tym przypadku właśnie utworzone wystąpienie, które jest powiązane z nowo utworzonym delegatem. Za każdym razem, gdy ten delegat jest wywoływany, metoda dynamiczna działa na powiązanym wystąpieniu .Example

Uwaga

Jest to przykład zrelaksowanych reguł delegowania powiązania wprowadzonego w .NET Framework 2.0 wraz z nowymi przeciążeniami Delegate.CreateDelegate metody. Aby uzyskać więcej informacji, zobacz klasę Delegate .

Delegat UseLikeStatic jest wywoływany, przekazując wystąpienie, Example które jest powiązane z delegatem UseLikeInstance . UseLikeInstance Następnie delegat jest wywoływany, aby oba delegaty działały w tym samym wystąpieniu Example. Zmiany w wartościach pola wewnętrznego są wyświetlane po każdym wywołaniu. UseLikeInstance Na koniec delegat jest powiązany z wystąpieniem obiektu DerivedFromExample, a wywołania delegata są powtarzane.

using System;
using System.Reflection;
using System.Reflection.Emit;

// These classes are for demonstration purposes.
//
public class Example
{
    private int id = 0;
    public Example(int id)
    {
        this.id = id;
    }
    public int ID { get { return id; }}
}

public class DerivedFromExample : Example
{
    public DerivedFromExample(int id) : base(id) {}
}

// Two delegates are declared: UseLikeInstance treats the dynamic
// method as if it were an instance method, and UseLikeStatic
// treats the dynamic method in the ordinary fashion.
//
public delegate int UseLikeInstance(int newID);
public delegate int UseLikeStatic(Example ex, int newID);

public class Demo
{
    public static void Main()
    {
        // This dynamic method changes the private id field. It has
        // no name; it returns the old id value (return type int);
        // it takes two parameters, an instance of Example and
        // an int that is the new value of id; and it is declared
        // with Example as the owner type, so it can access all
        // members, public and private.
        //
        DynamicMethod changeID = new DynamicMethod(
            "",
            typeof(int),
            new Type[] { typeof(Example), typeof(int) },
            typeof(Example)
        );

        // Get a FieldInfo for the private field 'id'.
        FieldInfo fid = typeof(Example).GetField(
            "id",
            BindingFlags.NonPublic | BindingFlags.Instance
        );

        ILGenerator ilg = changeID.GetILGenerator();

        // Push the current value of the id field onto the
        // evaluation stack. It's an instance field, so load the
        // instance of Example before accessing the field.
        ilg.Emit(OpCodes.Ldarg_0);
        ilg.Emit(OpCodes.Ldfld, fid);

        // Load the instance of Example again, load the new value
        // of id, and store the new field value.
        ilg.Emit(OpCodes.Ldarg_0);
        ilg.Emit(OpCodes.Ldarg_1);
        ilg.Emit(OpCodes.Stfld, fid);

        // The original value of the id field is now the only
        // thing on the stack, so return from the call.
        ilg.Emit(OpCodes.Ret);

        // Create a delegate that uses changeID in the ordinary
        // way, as a static method that takes an instance of
        // Example and an int.
        //
        UseLikeStatic uls =
            (UseLikeStatic) changeID.CreateDelegate(
                typeof(UseLikeStatic)
            );

        // Create an instance of Example with an id of 42.
        //
        Example ex = new Example(42);

        // Create a delegate that is bound to the instance of
        // of Example. This is possible because the first
        // parameter of changeID is of type Example. The
        // delegate has all the parameters of changeID except
        // the first.
        UseLikeInstance uli =
            (UseLikeInstance) changeID.CreateDelegate(
                typeof(UseLikeInstance),
                ex
            );

        // First, change the value of id by calling changeID as
        // a static method, passing in the instance of Example.
        //
        Console.WriteLine(
            "Change the value of id; previous value: {0}",
            uls(ex, 1492)
        );

        // Change the value of id again using the delegate bound
        // to the instance of Example.
        //
        Console.WriteLine(
            "Change the value of id; previous value: {0}",
            uli(2700)
        );

        Console.WriteLine("Final value of id: {0}", ex.ID);

        // Now repeat the process with a class that derives
        // from Example.
        //
        DerivedFromExample dfex = new DerivedFromExample(71);

        uli = (UseLikeInstance) changeID.CreateDelegate(
                typeof(UseLikeInstance),
                dfex
            );

        Console.WriteLine(
            "Change the value of id; previous value: {0}",
            uls(dfex, 73)
        );
        Console.WriteLine(
            "Change the value of id; previous value: {0}",
            uli(79)
        );
        Console.WriteLine("Final value of id: {0}", dfex.ID);
    }
}

/* This code example produces the following output:

Change the value of id; previous value: 42
Change the value of id; previous value: 1492
Final value of id: 2700
Change the value of id; previous value: 71
Change the value of id; previous value: 73
Final value of id: 79
 */

Uwagi

To przeciążenie metody tworzy delegata powiązanego z określonym obiektem. Taki delegat mówi się, że zostanie zamknięty w związku z pierwszym argumentem. Mimo że metoda jest statyczna, działa tak, jakby była to metoda wystąpienia; wystąpienie to target.

To przeciążenie metody wymaga target tego samego typu co pierwszy parametr metody dynamicznej lub do przypisania do tego typu (na przykład klasy pochodnej). delegateType Podpis zawiera wszystkie parametry metody dynamicznej, z wyjątkiem pierwszej. Jeśli na przykład metoda dynamiczna ma parametry , i , ma parametry StringInt32 i Byte; target jest typu String.delegateTypeByteInt32

CreateDelegate Wywołanie metody lub Invoke metody kończy metodę dynamiczną. Wszelkie dalsze próby zmiany metody dynamicznej, takie jak modyfikowanie definicji parametrów lub emitowanie większej liczby języków pośrednich firmy Microsoft (MSIL), są ignorowane; nie jest zgłaszany żaden wyjątek.

Aby utworzyć treść metody dla metody dynamicznej, gdy masz własny generator MSIL, wywołaj GetDynamicILInfo metodę DynamicILInfo w celu uzyskania obiektu. Jeśli nie masz własnego generatora MSIL, wywołaj GetILGenerator metodę ILGenerator , aby uzyskać obiekt, którego można użyć do wygenerowania treści metody.

Dotyczy

.NET 9 i inne wersje
Produkt Wersje
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1