DynamicMethod.CreateDelegate メソッド

定義

動的メソッドを完了し、それを実行するために使用できるデリゲートを作成します。

オーバーロード

名前 説明
CreateDelegate(Type)

動的メソッドを完了し、それを実行するために使用できるデリゲートを作成します。

CreateDelegate(Type, Object)

動的メソッドを完了し、デリゲートの実行に使用できるデリゲートを作成します。デリゲートの型とデリゲートがバインドされているオブジェクトを指定します。

CreateDelegate(Type)

動的メソッドを完了し、それを実行するために使用できるデリゲートを作成します。

public:
 Delegate ^ CreateDelegate(Type ^ delegateType);
public:
 override 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);
public override sealed Delegate CreateDelegate(Type delegateType);
[<System.Runtime.InteropServices.ComVisible(true)>]
member this.CreateDelegate : Type -> Delegate
[<System.Runtime.InteropServices.ComVisible(true)>]
override this.CreateDelegate : Type -> Delegate
override this.CreateDelegate : Type -> Delegate
Public Function CreateDelegate (delegateType As Type) As Delegate
Public Overrides NotOverridable Function CreateDelegate (delegateType As Type) As Delegate

パラメーター

delegateType
Type

シグネチャが動的メソッドのシグネチャと一致するデリゲート型。

返品

動的メソッドの実行に使用できる、指定した型のデリゲート。

属性

例外

動的メソッドにはメソッド本体がありません。

delegateType には、パラメーターの数が間違っているか、パラメーターの型が間違っています。

次のコード例では、2 つのパラメーターを受け取る動的メソッドを作成します。 この例では、最初のパラメーターをコンソールに出力する単純な関数本体を出力し、2 番目のパラメーターをメソッドの戻り値として使用します。 この例では、デリゲートを作成してメソッドを完成させ、さまざまなパラメーターでデリゲートを呼び出し、最後に Invoke メソッドを使用して動的メソッドを呼び出します。

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);
    }
}
Imports System.Reflection
Imports System.Reflection.Emit

Public Class Test
    ' Declare a delegate that will be used to execute the completed
    ' dynamic method. 
    Private Delegate Function HelloInvoker(ByVal msg As String, _
        ByVal ret As Integer) As Integer

    Public Shared Sub Main()
        ' Create an array that specifies the types of the parameters
        ' of the dynamic method. This method has a String parameter
        ' and an Integer parameter.
        Dim helloArgs() As Type = {GetType(String), GetType(Integer)}

        ' 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 Test class.
        Dim hello As New DynamicMethod("Hello", _
            GetType(Integer), _
            helloArgs, _
            GetType(Test).Module)

        ' Create an array that specifies the parameter types of the
        ' overload of Console.WriteLine to be used in Hello.
        Dim writeStringArgs() As Type = {GetType(String)}
        ' Get the overload of Console.WriteLine that has one
        ' String parameter.
        Dim writeString As MethodInfo = GetType(Console). _
            GetMethod("WriteLine", writeStringArgs) 

        ' Get an ILGenerator and emit a body for the dynamic method.
        Dim il As ILGenerator = 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, Nothing)
        ' 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.
    Dim hi As HelloInvoker = _
            hello.CreateDelegate(GetType(HelloInvoker))

        ' Use the delegate to execute the dynamic method. Save and
        ' print the return value.
        Dim retval As Integer = hi(vbCrLf & "Hello, World!", 42)
        Console.WriteLine("Executing delegate hi(""Hello, World!"", 42) returned " _
            & retval)

        ' Do it again, with different arguments.
        retval = hi(vbCrLf & "Hi, Mom!", 5280)
        Console.WriteLine("Executing delegate hi(""Hi, Mom!"", 5280) returned " _
            & retval)

        ' Create an array of arguments to use with the Invoke method.
        Dim invokeArgs() As Object = {vbCrLf & "Hello, 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. Note that this overload of Invoke is 
        ' inherited from MethodBase, and simply calls the more 
        ' complete overload of Invoke.
        Dim objRet As Object = hello.Invoke(Nothing, invokeArgs)
        Console.WriteLine("hello.Invoke returned " & objRet)
    End Sub
End Class

' This code example produces the following output:
'
'Hello, World!
'Executing delegate hi("Hello, World!", 42) returned 42
'
'Hi, Mom!
'Executing delegate hi("Hi, Mom!", 5280) returned 5280
'
'Hello, World!
'hello.Invoke returned 42
'

注釈

CreateDelegate メソッドまたは Invoke メソッドを呼び出すと、動的メソッドが完了します。 パラメータ定義の変更や、Microsoft Intermediate Language (MSIL) の追加生成など、ダイナミックメソッドの変更を試みても無視されます。例外はスローされません。

独自の MSIL ジェネレーターがある場合に動的メソッドのメソッド本体を作成するには、 GetDynamicILInfo メソッドを呼び出して DynamicILInfo オブジェクトを取得します。 独自の MSIL ジェネレーターがない場合は、 GetILGenerator メソッドを呼び出して、メソッド本体の生成に使用できる ILGenerator オブジェクトを取得します。

こちらもご覧ください

適用対象

CreateDelegate(Type, Object)

動的メソッドを完了し、デリゲートの実行に使用できるデリゲートを作成します。デリゲートの型とデリゲートがバインドされているオブジェクトを指定します。

public:
 Delegate ^ CreateDelegate(Type ^ delegateType, System::Object ^ target);
public:
 override Delegate ^ CreateDelegate(Type ^ delegateType, System::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);
public override sealed Delegate CreateDelegate(Type delegateType, object target);
[<System.Runtime.InteropServices.ComVisible(true)>]
member this.CreateDelegate : Type * obj -> Delegate
[<System.Runtime.InteropServices.ComVisible(true)>]
override this.CreateDelegate : Type * obj -> Delegate
override this.CreateDelegate : Type * obj -> Delegate
Public Function CreateDelegate (delegateType As Type, target As Object) As Delegate
Public Overrides NotOverridable Function CreateDelegate (delegateType As Type, target As Object) As Delegate

パラメーター

delegateType
Type

シグネチャが動的メソッドのシグネチャと一致し、最初のパラメーターを引いたデリゲート型。

target
Object

デリゲートがバインドされているオブジェクト。 動的メソッドの最初のパラメーターと同じ型である必要があります。

返品

指定した型のデリゲート。指定したターゲット オブジェクトを使用して動的メソッドを実行するために使用できます。

属性

例外

動的メソッドにはメソッド本体がありません。

target は動的メソッドの最初のパラメーターと同じ型ではなく、その型に割り当てできません。

-または-

delegateType には、パラメーターの数が間違っているか、パラメーターの型が間違っています。

次のコード例では、 DynamicMethod を型のインスタンスにバインドするデリゲートを作成し、メソッドが呼び出されるたびに同じインスタンスで動作するようにします。

このコード例では、プライベート フィールドExampleという名前のクラス、最初のクラスから派生する DerivedFromExample という名前のクラス、UseLikeStaticを返し、Int32 型とExampleのパラメーターを持つ Int32 という名前のデリゲート型、および UseLikeInstance を返し、Int32型の 1 つのパラメーターを持つ Int32 という名前のデリゲート型を定義します。

次に、このコード例では、DynamicMethodのインスタンスのプライベート フィールドを変更し、前の値を返すExampleを作成します。

Note

一般に、クラスの内部フィールドを変更することは、オブジェクト指向のコーディング手法としては適していません。

このコード例では、 Example のインスタンスを作成し、次に 2 つのデリゲートを作成します。 1 つ目は、動的メソッドと同じパラメーターを持つ UseLikeStatic型です。 2 つ目は UseLikeInstance 型で、最初のパラメーター ( Example 型) がありません。 このデリゲートは、 CreateDelegate(Type, Object) メソッド オーバーロードを使用して作成されます。そのメソッド オーバーロードの 2 番目のパラメーターは、 Exampleのインスタンスです。この場合、作成したインスタンスは、新しく作成されたデリゲートにバインドされます。 そのデリゲートが呼び出されるたびに、動的メソッドは Exampleのバインドされたインスタンスに対して動作します。

Note

これは、.NET Framework 2.0 で導入されたデリゲート バインディングの緩和された規則と、 Delegate.CreateDelegate メソッドの新しいオーバーロードの例です。 詳細については、Delegate クラスを参照してください。

UseLikeStatic デリゲートが呼び出され、UseLikeInstance デリゲートにバインドされているExampleのインスタンスが渡されます。 その後、 UseLikeInstance デリゲートが呼び出され、両方のデリゲートが Exampleの同じインスタンスに対して動作します。 内部フィールドの値の変更は、各呼び出しの後に表示されます。 最後に、 UseLikeInstance デリゲートは DerivedFromExampleのインスタンスにバインドされ、デリゲート呼び出しが繰り返されます。

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
 */
Imports System.Reflection
Imports System.Reflection.Emit

' These classes are for demonstration purposes.
'
Public Class Example
    Private _id As Integer = 0
    
    Public Sub New(ByVal newId As Integer) 
        _id = newId    
    End Sub
    
    Public ReadOnly Property ID() As Integer 
        Get
            Return _id
        End Get
    End Property 
End Class

Public Class DerivedFromExample
    Inherits Example
    
    Public Sub New(ByVal newId As Integer) 
        MyBase.New(newId)
    End Sub
End Class
 
' 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 Function UseLikeInstance(ByVal newID As Integer) _
    As Integer 
Public Delegate Function UseLikeStatic(ByVal ex As Example, _
    ByVal newID As Integer) As Integer 

Public Class Demo
    
    Public Shared Sub Main() 
        ' This dynamic method changes the private _id field. It 
        ' has no name; it returns the old _id value (return type 
        ' Integer); it takes two parameters, an instance of Example 
        ' and an Integer 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.
        '
        Dim changeID As New DynamicMethod( _
            "", _
            GetType(Integer), _
            New Type() {GetType(Example), GetType(Integer)}, _
            GetType(Example) _
        )
        
        ' Get a FieldInfo for the private field '_id'.
        Dim fid As FieldInfo = GetType(Example).GetField( _
            "_id", _
            BindingFlags.NonPublic Or BindingFlags.Instance _
        )
        
        Dim ilg As ILGenerator = 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 Integer.
        '
        Dim uls As UseLikeStatic = CType( _
            changeID.CreateDelegate(GetType(UseLikeStatic)), _
            UseLikeStatic _
        )
        
        ' Create an instance of Example with an id of 42.
        '
        Dim ex As 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.
        Dim uli As UseLikeInstance = CType( _
            changeID.CreateDelegate( _
                GetType(UseLikeInstance), _
                ex), _
            UseLikeInstance _
        )
        
        ' 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.
        '
        Dim dfex As New DerivedFromExample(71)

        uli = CType( _
            changeID.CreateDelegate( _
                GetType(UseLikeInstance), _
                dfex), _
            UseLikeInstance _
        )

        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)

    End Sub
End Class

' 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'

注釈

このメソッド オーバーロードは、特定のオブジェクトにバインドされたデリゲートを作成します。 このようなデリゲートは、最初の引数で閉じられると言われます。 メソッドは静的ですが、インスタンス メソッドであるかのように機能します。インスタンスが target

このメソッドオーバーロードでは、 target 動的メソッドの最初のパラメーターと同じ型であるか、その型 (派生クラスなど) に割り当て可能である必要があります。 delegateTypeのシグネチャには、最初のメソッドを除く動的メソッドのすべてのパラメーターがあります。 たとえば、動的メソッドにパラメーター StringInt32、および Byteがある場合、 delegateType にはパラメーター Int32Byteが含まれます。 target 型は String

CreateDelegate メソッドまたは Invoke メソッドを呼び出すと、動的メソッドが完了します。 パラメータ定義の変更や、Microsoft Intermediate Language (MSIL) の追加生成など、ダイナミックメソッドの変更を試みても無視されます。例外はスローされません。

独自の MSIL ジェネレーターがある場合に動的メソッドのメソッド本体を作成するには、 GetDynamicILInfo メソッドを呼び出して DynamicILInfo オブジェクトを取得します。 独自の MSIL ジェネレーターがない場合は、 GetILGenerator メソッドを呼び出して、メソッド本体の生成に使用できる ILGenerator オブジェクトを取得します。

適用対象