DynamicMethod.CreateDelegate Method (Type, Object)

Completes the dynamic method and creates a delegate that can be used to execute it, specifying the delegate type and an object the delegate is bound to.

Namespace:  System.Reflection.Emit
Assembly:  mscorlib (in mscorlib.dll)

'Declaration
<ComVisibleAttribute(True)> _
Public Overrides NotOverridable Function CreateDelegate ( _
	delegateType As Type, _
	target As Object _
) As Delegate

Parameters

delegateType
Type: System.Type

A delegate type whose signature matches that of the dynamic method, minus the first parameter.

target
Type: System.Object

An object the delegate is bound to. Must be of the same type as the first parameter of the dynamic method.

Return Value

Type: System.Delegate
A delegate of the specified type, which can be used to execute the dynamic method with the specified target object.

ExceptionCondition
InvalidOperationException

The dynamic method has no method body.

ArgumentException

target is not the same type as the first parameter of the dynamic method, and is not assignable to that type.

-or-

delegateType has the wrong number of parameters or the wrong parameter types.

This method overload creates a delegate bound to a particular object. Such a delegate is said to be closed over its first argument. Although the method is static, it acts as if it were an instance method; the instance is target.

This method overload requires target to be of the same type as the first parameter of the dynamic method, or to be assignable to that type (for example, a derived class). The signature of delegateType has all the parameters of the dynamic method except the first. For example, if the dynamic method has the parameters String, Int32, and Byte, then delegateType has the parameters Int32 and Byte; target is of type String.

Calling the CreateDelegate method or the Invoke method completes the dynamic method. Any further attempt to alter the dynamic method, such as modifying parameter definitions or emitting more Microsoft intermediate language (MSIL), is ignored; no exception is thrown.

To create a method body for a dynamic method when you have your own MSIL generator, call the GetDynamicILInfo method to obtain a DynamicILInfo object. If you do not have your own MSIL generator, call the GetILGenerator method to obtain an ILGenerator object that can be used to generate the method body.

The following code example creates delegate that binds a DynamicMethod to an instance of a type, so that the method acts on the same instance each time it is invoked.

The code example defines a class named Example with a private field, a class named DerivedFromxample that derives from the first class, a delegate type named UseLikeStatic that returns Int32 and has parameters of type Example and Int32, and a delegate type named UseLikeInstance that returns Int32 and has one parameter of type Int32.

The example code then creates a DynamicMethod that changes the private field of an instance of Example and returns the previous value.

NoteNote

In general, changing the internal fields of classes is not good object-oriented coding practice.

The example code creates an instance of Example and then creates two delegates. The first is of type UseLikeStatic, which has the same parameters as the dynamic method. The second is of type UseLikeInstance, which lacks the first parameter (of type Example). This delegate is created using the CreateDelegate(Type, Object) method overload; the second parameter of that method overload is an instance of Example, in this case the instance just created, which is bound to the newly created delegate. Whenever that delegate is invoked, the dynamic method acts on the bound instance of Example.

NoteNote

This is an example of the relaxed rules for delegate binding introduced in the .NET Framework 2.0, along with new overloads of the Delegate.CreateDelegate method. For more information, see the Delegate class.

The UseLikeStatic delegate is invoked, passing in the instance of Example that is bound to the UseLikeInstance delegate. Then the UseLikeInstance delegate is invoked, so that both delegates act on the same instance of Example. The changes in the values of the internal field are displayed after each call. Finally, a UseLikeInstance delegate is bound to an instance of DerivedFromxample, and the delegate calls are repeated.

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

.NET Framework

Supported in: 4.6, 4.5, 4, 3.5, 3.0, 2.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Supported in: Windows Phone 8.1

Supported in: Windows Phone Silverlight 8.1

Supported in: Windows Phone Silverlight 8
Was this page helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2015 Microsoft