Compartir a través de


DynamicMethod.CreateDelegate Method (Type, Object)

Microsoft Silverlight will reach end of support after October 2021. Learn more.

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)

Syntax

'Declaration
<ComVisibleAttribute(True)> _
<SecuritySafeCriticalAttribute> _
Public Overrides NotOverridable Function CreateDelegate ( _
    delegateType As Type, _
    target As Object _
) As Delegate
[ComVisibleAttribute(true)]
[SecuritySafeCriticalAttribute]
public override sealed Delegate CreateDelegate(
    Type delegateType,
    Object target
)

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.

Exceptions

Exception Condition
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.

Remarks

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.

Examples

The following example shows how to define a dynamic method, and then create a delegate with an object that is bound to the first parameter of the method.

The example defines a class named Base with a field named Number, and a class named DerivedFromBase that derives from the first class. The example defines two delegate types: one named UseLikeStatic that returns Int32 and has parameters of type Base and Int32, and another named UseLikeInstance that returns Int32 and has one parameter of type Int32.

The example then creates a DynamicMethod that changes the Number field of an instance of Base and returns the previous value.

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

NoteNote:

This is an example of the relaxed rules for delegate binding, which are also supported by the Delegate.CreateDelegate method. For more information, see the Delegate class.

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

Imports System.Reflection
Imports System.Reflection.Emit

' These classes are for demonstration purposes.
'
Public Class Base
   Public Number As Integer = 0

   Public Sub New(ByVal initialNumber As Integer)
      Number = initialNumber 
   End Sub
End Class

Public Class DerivedFromBase
   Inherits Base

   Public Sub New(ByVal initialNumber As Integer)
      MyBase.New(initialNumber)
   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 number As Integer) _
    As Integer
Public Delegate Function UseLikeStatic(ByVal b As Base, _
    ByVal number As Integer) As Integer

Public Class Example

   Public Shared Sub Demo(ByVal outputBlock As System.Windows.Controls.TextBlock)
      ' This dynamic method sets the public Number field of an instance
      ' of Base, and returns the previous value. The method has no name. 
      ' It takes two parameters, an instance of Base and an Integer that
      ' is the new field value. 
      '
      Dim changeNumber As New DynamicMethod( _
          "", _
          GetType(Integer), _
          New Type() {GetType(Base), GetType(Integer)} _
      )

      ' Get a FieldInfo for the public field 'Number'.
      Dim fnum As FieldInfo = GetType(Base).GetField( _
          "Number", _
          BindingFlags.Public Or BindingFlags.Instance _
      )

      Dim ilg As ILGenerator = changeNumber.GetILGenerator()

      ' Push the current value of the Number field onto the 
      ' evaluation stack. It's an instance field, so load the
      ' instance of Base before accessing the field.
      ilg.Emit(OpCodes.Ldarg_0)
      ilg.Emit(OpCodes.Ldfld, fnum)

      ' Load the instance of Base 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, fnum)

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


      ' Create a delegate that uses changeNumber in the ordinary
      ' way, as a static method that takes an instance of
      ' Base and an Integer.
      '
      Dim uls As UseLikeStatic = CType( _
          changeNumber.CreateDelegate(GetType(UseLikeStatic)),  _
          UseLikeStatic _
      )

      ' Create an instance of Base with an id of 42.
      '
      Dim ba As New Base(42)

      ' Create a delegate that is bound to the instance of 
      ' of Base. This is possible because the first 
      ' parameter of changeNumber is of type Base. The 
      ' delegate has all the parameters of changeNumber except
      ' the first.
      Dim uli As UseLikeInstance = CType( _
          changeNumber.CreateDelegate( _
              GetType(UseLikeInstance), _
              ba),  _
          UseLikeInstance _
      )

      ' First, change the value of Number by calling changeNumber as
      ' a static method, passing in the instance of Base.
      '
      outputBlock.Text &= String.Format( _
          "Change the value of Number; previous value: {0}", _
          uls(ba, 1492) _
      ) & vbCrLf

      ' Change the value of Number again using the delegate 
      ' bound to the instance of Base.
      '
      outputBlock.Text &= String.Format( _
          "Change the value of Number; previous value: {0}", _
          uli(2700) _
      ) & vbCrLf

      outputBlock.Text &= String.Format("Final value of Number: {0}", ba.Number) & vbCrLf


      ' Now repeat the process with a class that derives
      ' from Base.
      '
      Dim dfba As New DerivedFromBase(71)

      uli = CType( _
          changeNumber.CreateDelegate( _
              GetType(UseLikeInstance), _
              dfba),  _
          UseLikeInstance _
      )

      outputBlock.Text &= String.Format( _
          "Change the value of Number; previous value: {0}", _
          uls(dfba, 73) _
      ) & vbCrLf
      outputBlock.Text &= String.Format( _
          "Change the value of Number; previous value: {0}", _
          uli(79) _
      ) & vbCrLf
      outputBlock.Text &= String.Format("Final value of Number: {0}", dfba.Number) & vbCrLf

   End Sub
End Class

' This example produces the following output:
'
'Change the value of Number; previous value: 42
'Change the value of Number; previous value: 1492
'Final value of Number: 2700
'Change the value of Number; previous value: 71
'Change the value of Number; previous value: 73
'Final value of Number: 79' 
using System;
using System.Reflection;
using System.Reflection.Emit;

// These classes are for demonstration purposes.
//
public class Base
{
   public int Number = 0;
   public Base(int initialNumber)
   {
      this.Number = initialNumber;
   }
}

public class DerivedFromBase : Base
{
   public DerivedFromBase(int initialNumber) : base(initialNumber) { }
}

// 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 newNumber);
public delegate int UseLikeStatic(Base ba, int newNumber);

public class Example
{
   public static void Demo(System.Windows.Controls.TextBlock outputBlock)
   {
      // This dynamic method sets the public Number field of an instance
      // of Base, and returns the previous value. The method has no name. 
      // It takes two parameters, an instance of Base and an Integer that
      // is the new field value. 
      //
      DynamicMethod changeNumber = new DynamicMethod(
          "",
          typeof(int),
          new Type[] { typeof(Base), typeof(int) }
      );

      // Get a FieldInfo for the public field 'Number'.
      FieldInfo fnum = typeof(Base).GetField(
          "Number",
          BindingFlags.Public | BindingFlags.Instance
      );

      ILGenerator ilg = changeNumber.GetILGenerator();

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

      // Load the instance of Base again, load the new value 
      // of Number, and store the new field value. 
      ilg.Emit(OpCodes.Ldarg_0);
      ilg.Emit(OpCodes.Ldarg_1);
      ilg.Emit(OpCodes.Stfld, fnum);

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


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

      // Create an instance of Base with a Number of 42.
      //
      Base ba = new Base(42);

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

      // First, change the value of Number by calling changeNumber as
      // a static method, passing in the instance of Base.
      //
      outputBlock.Text += String.Format(
          "Change the value of Number; previous value: {0}",
          uls(ba, 1492)
      ) + "\n";

      // Change the value of Number again using the delegate bound
      // to the instance of Base.
      //
      outputBlock.Text += String.Format(
          "Change the value of Number; previous value: {0}",
          uli(2700)
      ) + "\n";

      outputBlock.Text += String.Format("Final value of Number: {0}", ba.Number) + "\n";


      // Now repeat the process with a class that derives
      // from Base.
      //
      DerivedFromBase dfba = new DerivedFromBase(71);

      uli = (UseLikeInstance)changeNumber.CreateDelegate(
              typeof(UseLikeInstance),
              dfba
          );

      outputBlock.Text += String.Format(
          "Change the value of Number; previous value: {0}",
          uls(dfba, 73)
      ) + "\n";
      outputBlock.Text += String.Format(
          "Change the value of Number; previous value: {0}",
          uli(79)
      ) + "\n";
      outputBlock.Text += String.Format("Final value of Number: {0}", dfba.Number) + "\n";
   }
}

/* This example produces the following output:

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

Version Information

Silverlight

Supported in: 5, 4, 3

Silverlight for Windows Phone

Supported in: Windows Phone OS 7.1

Platforms

For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.