Compartir a través de


Delegate.CreateDelegate Method (Type, MethodInfo, Boolean)

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

Creates a delegate of the specified type to represent the specified static method, with the specified behavior on failure to bind.

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

Syntax

'Declaration
<SecuritySafeCriticalAttribute> _
Public Shared Function CreateDelegate ( _
    type As Type, _
    method As MethodInfo, _
    throwOnBindFailure As Boolean _
) As Delegate
[SecuritySafeCriticalAttribute]
public static Delegate CreateDelegate(
    Type type,
    MethodInfo method,
    bool throwOnBindFailure
)

Parameters

  • type
    Type: System.Type
    The type of delegate to create.
  • throwOnBindFailure
    Type: System.Boolean
    true to throw an exception if method cannot be bound; otherwise, false.

Return Value

Type: System.Delegate
A delegate of the specified type to represent the specified static method.

Exceptions

Exception Condition
ArgumentNullException

type is nulla null reference (Nothing in Visual Basic).

-or-

method is nulla null reference (Nothing in Visual Basic).

ArgumentException

type does not inherit MulticastDelegate.

-or-

type is not a RuntimeType. See Runtime Types in Reflection.

-or-

method cannot be bound, and throwOnBindFailure is true.

-or-

method is not a RuntimeMethodInfo. See Runtime Types in Reflection.

MissingMethodException

The Invoke method of type is not found.

MethodAccessException

The caller does not have access to method.

-or-

Application code attempts to access this member late-bound, for example, by using the Type.InvokeMember method.

Remarks

In Silverlight, method must specify an accessible method.

This method overload can create open static method delegates and open instance method delegates — that is, delegates that expose the hidden first argument of instance methods. For a detailed explanation, see the more general CreateDelegate(Type, Object, MethodInfo, Boolean) method overload, which allows you to create all combinations of open or closed delegates for instance or static methods.

NoteNote:

This method overload should be used when the delegate is not closed over its first argument, because it is somewhat faster in that case.

Compatible Parameter Types and Return Type

The parameter types and return type of a delegate must be compatible with the parameter types and return type of the method the delegate represents; the types do not have to match exactly.

A parameter of a delegate is compatible with the corresponding parameter of a method if the type of the delegate parameter is more restrictive than the type of the method parameter, because this guarantees that an argument passed to the delegate can be passed safely to the method.

Similarly, the return type of a delegate is compatible with the return type of a method if the return type of the method is more restrictive than the return type of the delegate, because this guarantees that the return value of the method can be cast safely to the return type of the delegate.

For example, given two types Base and Derived, such that Derived inherits Base, a delegate with a parameter of type Derived and a return type of Base can represent a method with a parameter of type Base and a return value of type Derived.

Platform Notes

Silverlight for Windows Phone Silverlight for Windows Phone

 CreateDelegate throws MissingMethodException when attempting to create a delegate with incorrect arguments. Delegate.CreateDelegate throws TargetInvocationException when called on a null object. Delegate.CreateDelegate throws MissingMethodException instead of ArgumentException for non-instance methods.

Examples

This section contains two code examples. The first example demonstrates the two kinds of delegates that can be created with this method overload: open over an instance method and open over a static method.

The second code example demonstrates compatible parameter types and return types.

Example 1

The following code example demonstrates the two ways a delegate can be created using this overload of the CreateDelegate method.

NoteNote:

There are two overloads of the CreateDelegate method that specify a MethodInfo but not a first argument; their functionality is the same except that one allows you to specify whether to throw on failure to bind, and the other always throws. This code example uses both overloads.

The example declares a class C with a static method M2 and an instance method M1, and two delegate types: D1 takes an instance of C and a string, and D2 takes a string.

A second class named Example contains the code that creates the delegates.

  • A delegate of type D1, representing an open instance method, is created for the instance method M1. An instance must be passed when the delegate is invoked.

  • A delegate of type D2, representing an open static method, is created for the static method M2.

Imports System.Reflection
Imports System.Security.Permissions

' Declare three delegate types for demonstrating the combinations
' of Shared versus instance methods and open versus closed
' delegates.
'
Public Delegate Sub D1(ByVal c As C, ByVal s As String)
Public Delegate Sub D2(ByVal s As String)
Public Delegate Sub D3()

' A sample class with an instance method and a Shared method.
'
Public Class C
   Private id As Integer
   Public Sub New(ByVal id As Integer)
      Me.id = id
   End Sub 'New

   Public Sub M1(ByVal s As String)
      outputBlock.Text &= String.Format("Instance method M1 on C:  id = {0}, s = {1}", _
          Me.id, s) & vbCrLf
   End Sub

   Public Shared Sub M2(ByVal s As String)
      outputBlock.Text &= String.Format("Shared method M2 on C:  s = {0}", s) & vbCrLf
   End Sub

   ' Provide access to the TextBlock for output.
   Friend Shared outputBlock As System.Windows.Controls.TextBlock
End Class

Public Class Example

   Public Shared Sub Demo(ByVal outputBlock As System.Windows.Controls.TextBlock)

      ' Initialize class C for output to the TextBlock.
      C.outputBlock = outputBlock

      Dim c1 As New C(42)

      ' Get a MethodInfo for each method.
      '
      Dim mi1 As MethodInfo = GetType(C).GetMethod("M1", _
          BindingFlags.Public Or BindingFlags.Instance)
      Dim mi2 As MethodInfo = GetType(C).GetMethod("M2", _
          BindingFlags.Public Or BindingFlags.Static)

      Dim d1 As D1
      Dim d2 As D2
      Dim d3 As D3


      outputBlock.Text &= vbLf & "An instance method closed over C." & vbCrLf
      ' In this case, the delegate and the
      ' method must have the same list of argument types; use
      ' delegate type D2 with instance method M1.
      '
      Dim test As [Delegate] = _
          [Delegate].CreateDelegate(GetType(D2), c1, mi1, False)

      ' Because False was specified for throwOnBindFailure 
      ' in the call to CreateDelegate, the variable 'test'
      ' contains Nothing if the method fails to bind (for 
      ' example, if mi1 happened to represent a method of 
      ' some class other than C).
      '
      If test IsNot Nothing Then
         d2 = CType(test, D2)

         ' The same instance of C is used every time the
         ' delegate is invoked.
         d2("Hello, World!")
         d2("Hi, Mom!")
      End If


      outputBlock.Text &= vbLf & "An open instance method." & vbCrLf
      ' In this case, the delegate has one more 
      ' argument than the instance method; this argument comes
      ' at the beginning, and represents the hidden instance
      ' argument of the instance method. Use delegate type D1
      ' with instance method M1.
      '
      d1 = CType([Delegate].CreateDelegate(GetType(D1), Nothing, mi1), D1)

      ' An instance of C must be passed in each time the 
      ' delegate is invoked.
      '
      d1(c1, "Hello, World!")
      d1(New C(5280), "Hi, Mom!")


      outputBlock.Text &= vbLf & "An open Shared method." & vbCrLf
      ' In this case, the delegate and the method must 
      ' have the same list of argument types; use delegate type
      ' D2 with Shared method M2.
      '
      d2 = CType([Delegate].CreateDelegate(GetType(D2), Nothing, mi2), D2)

      ' No instances of C are involved, because this is a Shared
      ' method. 
      '
      d2("Hello, World!")
      d2("Hi, Mom!")


      outputBlock.Text &= vbLf & "A Shared method closed over the first argument (String)." & vbCrLf
      ' The delegate must omit the first argument of the method.
      ' A string is passed as the firstArgument parameter, and 
      ' the delegate is bound to this string. Use delegate type 
      ' D3 with Shared method M2. 
      '
      d3 = CType([Delegate].CreateDelegate(GetType(D3), "Hello, World!", mi2), D3)

      ' Each time the delegate is invoked, the same string is
      ' used.
      d3()

   End Sub
End Class

' This code example produces the following output:
'
'An instance method closed over C.
'Instance method M1 on C:  id = 42, s = Hello, World!
'Instance method M1 on C:  id = 42, s = Hi, Mom!
'
'An open instance method.
'Instance method M1 on C:  id = 42, s = Hello, World!
'Instance method M1 on C:  id = 5280, s = Hi, Mom!
'
'An open Shared method.
'Shared method M2 on C:  s = Hello, World!
'Shared method M2 on C:  s = Hi, Mom!
'
'A Shared method closed over the first argument (String).
'Shared method M2 on C:  s = Hello, World!
' 
using System;
using System.Reflection;
using System.Security.Permissions;

// Declare three delegate types for demonstrating the combinations
// of static versus instance methods and open versus closed
// delegates.
//
public delegate void D1(C c, string s);
public delegate void D2(string s);
public delegate void D3();

// A sample class with an instance method and a static method.
//
public class C
{
   private int id;
   public C(int id) { this.id = id; }

   public void M1(string s)
   {
      outputBlock.Text += String.Format("Instance method M1 on C:  id = {0}, s = {1}",
          this.id, s) + "\n";
   }

   public static void M2(string s)
   {
      outputBlock.Text += String.Format("Static method M2 on C:  s = {0}", s) + "\n";
   }

   internal static System.Windows.Controls.TextBlock outputBlock;
}

public class Example
{
   public static void Demo(System.Windows.Controls.TextBlock outputBlock)
   {
      // Initialize class C for output to the TextBlock control.
      C.outputBlock = outputBlock;

      C c1 = new C(42);

      // Get a MethodInfo for each method.
      //
      MethodInfo mi1 = typeof(C).GetMethod("M1",
          BindingFlags.Public | BindingFlags.Instance);
      MethodInfo mi2 = typeof(C).GetMethod("M2",
          BindingFlags.Public | BindingFlags.Static);

      D1 d1;
      D2 d2;
      D3 d3;


      outputBlock.Text += "\nAn instance method closed over C." + "\n";
      // In this case, the delegate and the
      // method must have the same list of argument types; use
      // delegate type D2 with instance method M1.
      //
      Delegate test =
          Delegate.CreateDelegate(typeof(D2), c1, mi1, false);

      // Because false was specified for throwOnBindFailure 
      // in the call to CreateDelegate, the variable 'test'
      // contains null if the method fails to bind (for 
      // example, if mi1 happened to represent a method of  
      // some class other than C).
      //
      if (test != null)
      {
         d2 = (D2)test;

         // The same instance of C is used every time the 
         // delegate is invoked.
         d2("Hello, World!");
         d2("Hi, Mom!");
      }


      outputBlock.Text += "\nAn open instance method." + "\n";
      // In this case, the delegate has one more 
      // argument than the instance method; this argument comes
      // at the beginning, and represents the hidden instance
      // argument of the instance method. Use delegate type D1
      // with instance method M1.
      //
      d1 = (D1)Delegate.CreateDelegate(typeof(D1), null, mi1);

      // An instance of C must be passed in each time the 
      // delegate is invoked.
      //
      d1(c1, "Hello, World!");
      d1(new C(5280), "Hi, Mom!");


      outputBlock.Text += "\nAn open static method." + "\n";
      // In this case, the delegate and the method must 
      // have the same list of argument types; use delegate type
      // D2 with static method M2.
      //
      d2 = (D2)Delegate.CreateDelegate(typeof(D2), null, mi2);

      // No instances of C are involved, because this is a static
      // method. 
      //
      d2("Hello, World!");
      d2("Hi, Mom!");


      outputBlock.Text += "\nA static method closed over the first argument (String)." + "\n";
      // The delegate must omit the first argument of the method.
      // A string is passed as the firstArgument parameter, and 
      // the delegate is bound to this string. Use delegate type 
      // D3 with static method M2. 
      //
      d3 = (D3)Delegate.CreateDelegate(typeof(D3),
          "Hello, World!", mi2);

      // Each time the delegate is invoked, the same string is
      // used.
      d3();
   }
}

/* This code example produces the following output:

An instance method closed over C.
Instance method M1 on C:  id = 42, s = Hello, World!
Instance method M1 on C:  id = 42, s = Hi, Mom!

An open instance method.
Instance method M1 on C:  id = 42, s = Hello, World!
Instance method M1 on C:  id = 5280, s = Hi, Mom!

An open static method.
Static method M2 on C:  s = Hello, World!
Static method M2 on C:  s = Hi, Mom!

A static method closed over the first argument (String).
Static method M2 on C:  s = Hello, World!
 */

Example 2

The following code example demonstrates compatibility of parameter types and return types.

NoteNote:

This code example uses the CreateDelegate(Type, MethodInfo) method overload. The use of other overloads that take MethodInfo is similar.

The code example defines a base class named Base and a class named Derived that derives from Base. The derived class has a static (Shared in Visual Basic) method named MyMethod with one parameter of type Base and a return type of Derived. The code example also defines a delegate named Example that has one parameter of type Derived and a return type of Base.

The code example demonstrates that the delegate named Example can be used to represent the method MyMethod. The method can be bound to the delegate because:

  • The parameter type of the delegate (Derived) is more restrictive than the parameter type of MyMethod (Base), so that it is always safe to pass the argument of the delegate to MyMethod.

  • The return type of MyMethod (Derived) is more restrictive than the parameter type of the delegate (Base), so that it is always safe to cast the return type of the method to the return type of the delegate.

The code example produces no output.

Imports System.Reflection

' Define two classes to use in the demonstration, a base class and 
' a class that derives from it.
'
Public Class Base
End Class

Public Class Derived
   Inherits Base

   ' Define a Shared method to use in the demonstration. The method 
   ' takes an instance of Base and returns an instance of Derived.  
   ' For the purposes of the demonstration, it is not necessary for 
   ' the method to do anything useful. 
   '
   Public Shared Function MyMethod(ByVal arg As Base) As Derived
      Dim dummy As Base = arg
      Return New Derived()
   End Function

End Class

' Define a delegate that takes an instance of Derived and returns an
' instance of Base.
'
Public Delegate Function Caller(ByVal arg As Derived) As Base

Public Class Example

   Public Shared Sub Demo(ByVal outputBlock As System.Windows.Controls.TextBlock)

      ' The binding flags needed to retrieve MyMethod.
      Dim flags As BindingFlags = _
          BindingFlags.Public Or BindingFlags.Static

      ' Get a MethodInfo that represents MyMethod.
      Dim minfo As MethodInfo = _
          GetType(Derived).GetMethod("MyMethod", flags)

      ' Demonstrate covariance of parameter types and contravariance
      ' of return types by using the delegate Caller to represent
      ' MyMethod. The delegate binds to the method because the
      ' parameter of the delegate is more restrictive than the 
      ' parameter of the method (that is, the delegate accepts an
      ' instance of Derived, which can always be safely passed to
      ' a parameter of type Base), and the return type of MyMethod
      ' is more restrictive than the return type of Caller (that
      ' is, the method returns an instance of Derived, which can
      ' always be safely cast to type Base). 
      '
      Dim ex As Caller = CType( _
          [Delegate].CreateDelegate(GetType(Caller), minfo),  _
          Caller _
      )

      ' Execute MyMethod using the delegate Caller.
      '        
      Dim b As Base = ex(New Derived())
   End Sub
End Class

' This example produces no output.
using System;
using System.Reflection;

// Define two classes to use in the demonstration, a base class and 
// a class that derives from it.
//
public class Base { }

public class Derived : Base
{
   // Define a static method to use in the demonstration. The method 
   // takes an instance of Base and returns an instance of Derived.  
   // For the purposes of the demonstration, it is not necessary for 
   // the method to do anything useful. 
   //
   public static Derived MyMethod(Base arg)
   {
      Base dummy = arg;
      return new Derived();
   }
}

// Define a delegate that takes an instance of Derived and returns an
// instance of Base.
//
public delegate Base Caller(Derived arg);

public class Example
{
   public static void Demo(System.Windows.Controls.TextBlock outputBlock)
   {
      // The binding flags needed to retrieve MyMethod.
      BindingFlags flags = BindingFlags.Public | BindingFlags.Static;

      // Get a MethodInfo that represents MyMethod.
      MethodInfo minfo = typeof(Derived).GetMethod("MyMethod", flags);

      // Demonstrate covariance of parameter types and contravariance
      // of return types by using the delegate Caller to represent
      // MyMethod. The delegate binds to the method because the
      // parameter of the delegate is more restrictive than the 
      // parameter of the method (that is, the delegate accepts an
      // instance of Derived, which can always be safely passed to
      // a parameter of type Base), and the return type of MyMethod
      // is more restrictive than the return type of Caller (that
      // is, the method returns an instance of Derived, which can
      // always be safely cast to type Base). 
      //
      Caller ex =
          (Caller)Delegate.CreateDelegate(typeof(Caller), minfo);

      // Execute MyMethod using the delegate Caller.
      //        
      Base b = ex(new Derived());
   }
}

// This code example produces no output.

Version Information

Silverlight

Supported in: 5, 4, 3

Silverlight for Windows Phone

Supported in: Windows Phone OS 7.1, Windows Phone OS 7.0

XNA Framework

Supported in: Xbox 360, Windows Phone OS 7.0

Platforms

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