System.Delegate.CreateDelegate 메서드

이 문서에서는 이 API에 대한 참조 설명서에 대한 추가 설명서를 제공합니다.

메서드는 CreateDelegate 지정된 형식의 대리자를 만듭니다.

CreateDelegate(Type, MethodInfo) 메서드

이 메서드 오버로드는 메서드 오버로드를 CreateDelegate(Type, MethodInfo, Boolean) 호출하고 에 대해 throwOnBindFailure지정하는 것과 true 같습니다.

예제

이 섹션에는 두 코드 예제가 있습니다. 첫 번째 예제에서는 이 메서드 오버로드를 사용하여 만들 수 있는 두 가지 유형의 대리자를 보여 줍니다. 인스턴스 메서드를 통해 열고 정적 메서드를 통해 엽니다.

두 번째 코드 예제에서는 호환되는 매개 변수 형식 및 반환 형식을 보여 줍니다.

예 1

다음 코드 예제에서는 메서드의 이 오버로드 CreateDelegate 를 사용하여 대리자를 만들 수 있는 두 가지 방법을 보여 줍니다.

참고 항목

첫 번째 인수는 지정하지만 첫 번째 인수는 지정 MethodInfo 하지 않는 메서드의 CreateDelegate 오버로드가 두 개 있습니다. 하나는 바인딩 실패를 throw할지 여부를 지정할 수 있고 다른 하나는 항상 throw한다는 점을 제외하고 해당 기능은 동일합니다. 이 코드 예제에서는 두 오버로드를 모두 사용합니다.

이 예제에서는 정적 메서드와 인스턴스 메서드 M1M2 를 사용하여 클래스 C 를 선언하고 두 개의 대리자 형식을 선언합니다. 인스턴스 D1C 와 문자열 D2 을 사용하고 문자열을 사용합니다.

명명된 Example 두 번째 클래스에는 대리자를 만드는 코드가 포함됩니다.

  • 열려 있는 인스턴스 메서드를 나타내는 형식 D1의 대리자가 인스턴스 메서드 M1에 대해 만들어집니다. 대리자를 호출할 때 인스턴스를 전달해야 합니다.
  • 정적 M2메서드에 대해 열려 있는 정적 메서드를 나타내는 형식D2의 대리자가 만들어집니다.
using System;
using System.Reflection;

// 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)
    {
        Console.WriteLine("Instance method M1 on C:  id = {0}, s = {1}",
            this.id, s);
    }

    public static void M2(string s)
    {
        Console.WriteLine("Static method M2 on C:  s = {0}", s);
    }
}

public class Example2
{
    public static void Main()
    {
        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;

        Console.WriteLine("\nAn instance method closed over C.");
        // 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!");
        }

        Console.WriteLine("\nAn open instance method.");
        // 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!");

        Console.WriteLine("\nAn open static method.");
        // 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!");

        Console.WriteLine("\nA static method closed over the first argument (String).");
        // 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!
 */
open System
open System.Reflection

// A sample class with an instance method and a static method.
type C(id) =
    member _.M1(s) =
        printfn $"Instance method M1 on C:  id = %i{id}, s = %s{s}"

    static member M2(s) =
        printfn $"Static method M2 on C:  s = %s{s}"
    
// Declare three delegate types for demonstrating the combinations
// of static versus instance methods and open versus closed
// delegates.
type D1 = delegate of C * string -> unit
type D2 = delegate of string -> unit
type D3 = delegate of unit -> unit

let c1 = C 42

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

printfn "\nAn instance method closed over C."

// In this case, the delegate and the
// method must have the same list of argument types use
// delegate type D2 with instance method M1.
let 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 then
    let d2 = test :?> D2

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

printfn "\nAn open instance method."

// 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.
let d1 = Delegate.CreateDelegate(typeof<D1>, null, mi1) :?> D1

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

printfn "\nAn open static method."
// In this case, the delegate and the method must
// have the same list of argument types use delegate type
// D2 with static method M2.
let d2 = Delegate.CreateDelegate(typeof<D2>, null, mi2) :?> D2

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

printfn "\nA static method closed over the first argument (String)."
// 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.
let d3 = Delegate.CreateDelegate(typeof<D3>, "Hello, World!", mi2) :?> D3

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

// 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!
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 C2, 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 C2
    Private id As Integer
    Public Sub New(ByVal id As Integer)
        Me.id = id
    End Sub

    Public Sub M1(ByVal s As String)
        Console.WriteLine("Instance method M1 on C2:  id = {0}, s = {1}",
            Me.id, s)
    End Sub

    Public Shared Sub M2(ByVal s As String)
        Console.WriteLine("Shared method M2 on C2:  s = {0}", s)
    End Sub
End Class

Public Class Example2

    Public Shared Sub Main()

        Dim c1 As New C2(42)

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

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


        Console.WriteLine(vbLf & "An instance method closed over C2.")
        ' 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 C2).
        '
        If test IsNot Nothing Then
            d2 = CType(test, D2)

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


        Console.WriteLine(vbLf & "An open instance method.")
        ' 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 C2 must be passed in each time the 
        ' delegate is invoked.
        '
        d1(c1, "Hello, World!")
        d1(New C2(5280), "Hi, Mom!")


        Console.WriteLine(vbLf & "An open Shared method.")
        ' 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 C2 are involved, because this is a Shared
        ' method. 
        '
        d2("Hello, World!")
        d2("Hi, Mom!")


        Console.WriteLine(vbLf & "A Shared method closed over the first argument (String).")
        ' 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 C2.
'Instance method M1 on C2:  id = 42, s = Hello, World!
'Instance method M1 on C2:  id = 42, s = Hi, Mom!
'
'An open instance method.
'Instance method M1 on C2:  id = 42, s = Hello, World!
'Instance method M1 on C2:  id = 5280, s = Hi, Mom!
'
'An open Shared method.
'Shared method M2 on C2:  s = Hello, World!
'Shared method M2 on C2:  s = Hi, Mom!
'
'A Shared method closed over the first argument (String).
'Shared method M2 on C2:  s = Hello, World!
'

예제 2

다음 코드 예제에서는 매개 변수 형식 및 반환 형식의 호환성을 보여 줍니다.

코드 예제에서는 명명 Base 된 기본 클래스와 에서 파생되는 클래스 Derived 를 정의합니다 Base. 파생 클래스에는 형식의 static 매개 변수 하나와 반환 형식 BaseDerived으로 명명 MyMethod 된 (SharedVisual Basic의 경우) 메서드가 있습니다. 또한 코드 예제에서는 형식의 매개 변수 하나와 반환 형식 DerivedBase이 있는 대리자도 Example 정의합니다.

코드 예제에서는 명명 Example 된 대리자를 사용하여 메서드 MyMethod를 나타낼 수 있음을 보여 줍니다. 다음과 같은 이유로 메서드를 대리자로 바인딩할 수 있습니다.

  • 대리자의 매개 변수 형식(Derived)은 (Base)의 MyMethod 매개 변수 형식보다 더 제한적이므로 항상 대리자의 인수를 전달해도 안전합니다MyMethod.
  • (Derived)의 MyMethod 반환 형식은 대리자의 매개 변수 형식보다 더 제한적이므로 메서드의 반환 형식을 항상 대리Base자의 반환 형식으로 캐스팅하는 것이 안전합니다.

코드 예제에서는 출력을 생성하지 않습니다.

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 Example5(Derived arg);

class Test
{
    public static void Main()
    {
        // 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 contravariance of parameter types and covariance
        // of return types by using the delegate Example5 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 Example5 (that
        // is, the method returns an instance of Derived, which can
        // always be safely cast to type Base).
        //
        Example5 ex =
            (Example5)Delegate.CreateDelegate(typeof(Example5), minfo);

        // Execute MyMethod using the delegate Example5.
        //
        Base b = ex(new Derived());
    }
}
open System
open System.Reflection

// Define two classes to use in the demonstration, a base class and
// a class that derives from it.
type Base() = class end

type Derived() =
    inherit 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.
    static member MyMethod(arg: Base) =
        Derived()

// Define a delegate that takes an instance of Derived and returns an
// instance of Base.
type Example = delegate of Derived -> Base

// The binding flags needed to retrieve MyMethod.
let flags = BindingFlags.Public ||| BindingFlags.Static

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

// Demonstrate contravariance of parameter types and covariance
// of return types by using the delegate Example 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 Example (that
// is, the method returns an instance of Derived, which can
// always be safely cast to type Base).
let ex = Delegate.CreateDelegate(typeof<Example>, minfo) :?> Example

// Execute MyMethod using the delegate Example.
let b = Derived() |> ex.Invoke
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 Example(ByVal arg As Derived) As Base

Module Test

    Sub Main()

        ' 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 contravariance of parameter types and covariance
        ' of return types by using the delegate Example 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 Example (that
        ' is, the method returns an instance of Derived, which can
        ' always be safely cast to type Base). 
        '
        Dim ex As Example = CType( _
            [Delegate].CreateDelegate(GetType(Example), minfo), _
            Example _
        )

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

CreateDelegate(Type, Object, MethodInfo)CreateDelegate(Type, Object, MethodInfo, Boolean) 메서드

이러한 두 오버로드의 기능은 바인딩 실패를 throw할지 여부를 지정할 수 있고 다른 하나는 항상 throw한다는 점을 제외하고 동일합니다.

대리자 형식과 메서드에는 호환되는 반환 형식이 있어야 합니다. 즉, 반환 형식을 반환 형식typemethod 할당할 수 있어야 합니다.

firstArgument이러한 오버로드에 대한 두 번째 매개 변수는 대리자가 나타내는 메서드의 첫 번째 인수입니다. 제공된 경우 firstArgument 대리자가 호출 firstArgument 될 때마다 전달 method 되고 대리자는 대리자에게 바인딩되며 대리자는 첫 번째 인수를 통해 닫혀 있다고 합니다. Visual Basic의 경우 method 대리자를 호출할 때 제공된 인수 목록에는 첫 번째 매개 변수를 제외한 모든 매개 변수가 포함됩니다. 인스턴스 메서드 firstArgument 인 경우 method 숨겨진 인스턴스 매개 변수(C#에서 또는 Visual Basic으로 표시 this 됨)로 Me 전달됩니다.staticShared

제공된 경우 firstArgument 첫 번째 매개 변수는 method 참조 형식이어야 하며 해당 형식과 firstArgument 호환되어야 합니다.

Important

Is(SharedVisual Basic의 경우method)이고 첫 번째 매개 변수가 형식이거나 ValueTypefirstArgument 값 형식 Object 일 수 있습니다.static 이 경우 firstArgument 자동으로 boxed됩니다. C# 또는 Visual Basic 함수 호출에서와 마찬가지로 다른 인수에는 자동 boxing이 발생하지 않습니다.

null 참조이고 method 인스턴스 메서드인 경우 firstArgument 결과는 대리자 형식 typemethod다음의 서명에 따라 달라집니다.

  • 시그니처에 type 숨겨진 첫 번째 매개 변수 method가 명시적으로 포함된 경우 대리자는 열려 있는 인스턴스 메서드를 나타낸다. 대리자를 호출하면 인수 목록의 첫 번째 인수가 숨겨진 인스턴스 매개 변수 method로 전달됩니다.
  • 서명 methodtype 일치하는 경우(즉, 모든 매개 변수 형식이 호환됨) 대리자는 null 참조를 통해 닫혀 있다고 합니다. 대리자를 호출하는 것은 null 인스턴스에서 인스턴스 메서드를 호출하는 것과 같으며 특히 유용하지는 않습니다.

null 참조이고 method 정적이면 firstArgument 결과는 대리자 형식 typemethod다음의 서명에 따라 달라집니다.

  • 시그니처 methodtype 일치(즉, 모든 매개 변수 형식이 호환됨)이면 대리자는 개방형 정적 메서드를 나타낸다. 정적 메서드에 가장 일반적인 경우입니다. 이 경우 메서드 오버로드를 사용하여 CreateDelegate(Type, MethodInfo) 약간 더 나은 성능을 얻을 수 있습니다.
  • 시그니처가 type 두 번째 매개 변수로 시작하고 나머지 매개 변수 method 형식이 호환되는 경우 대리자는 null 참조를 통해 닫힌 것으로 표시됩니다. 대리자를 호출하면 null 참조가 첫 번째 매개 변수 method에 전달됩니다.

예시

다음 코드 예제에서는 단일 대리자 형식이 나타낼 수 있는 모든 메서드를 보여 줍니다. 인스턴스 메서드를 통해 닫히고, 인스턴스 메서드를 열고, 정적 메서드를 통해 열고, 정적 메서드를 통해 닫힙니다.

코드 예제에서는 두 개의 클래스 C 를 정의하고 F형식의 인수가 하나 있는 대리자 형식 DC을 정의합니다. 클래스에는 일치하는 정적 메서드와 인스턴스 메서드 M1M3있으며 M4, 클래스 C 에는 인수가 없는 인스턴스 메서드 M2 도 있습니다.

명명된 Example 세 번째 클래스에는 대리자를 만드는 코드가 포함됩니다.

  • 형식 및 형식 CF의 인스턴스 메서드 M1 에 대해 대리자가 만들어집니다. 각 대리자는 각 형식의 인스턴스에 대해 닫힙니다. 형식 C 의 메서드 M1ID 바인딩된 인스턴스 및 인수의 속성을 표시합니다.
  • 형식 C메서드 M2 에 대한 대리자가 만들어집니다. 대리자의 인수가 인스턴스 메서드의 숨겨진 첫 번째 인수를 나타내는 열린 인스턴스 대리자입니다. 메서드에 다른 인수가 없습니다. 정적 메서드인 것처럼 호출됩니다.
  • 형식 및 형식 CF의 정적 메서드 M3 에 대해 대리자가 만들어집니다. 이는 열린 정적 대리자입니다.
  • 마지막으로 형식 C 및 형식F의 정적 메서드 M4 에 대해 대리자가 만들어집니다. 각 메서드는 선언 형식을 첫 번째 인수로 사용하고 형식의 인스턴스를 제공하므로 대리자는 첫 번째 인수를 통해 닫힙니다. 형식 C 의 메서드 M4ID 바인딩된 인스턴스 및 인수의 속성을 표시합니다.
using System;
using System.Reflection;

// Declare a delegate type. The object of this code example
// is to show all the methods this delegate can bind to.
//
public delegate void D(C1 c);

// Declare two sample classes, C1 and F. Class C1 has an ID
// property so instances can be identified.
//
public class C1
{
    private int id;
    public int ID { get { return id; } }
    public C1(int id) { this.id = id; }

    public void M1(C1 c)
    {
        Console.WriteLine("Instance method M1(C1 c) on C1:  this.id = {0}, c.ID = {1}",
            this.id, c.ID);
    }

    public void M2()
    {
        Console.WriteLine("Instance method M2() on C1:  this.id = {0}",
            this.id);
    }

    public static void M3(C1 c)
    {
        Console.WriteLine("Static method M3(C1 c) on C1:  c.ID = {0}", c.ID);
    }

    public static void M4(C1 c1, C1 c2)
    {
        Console.WriteLine("Static method M4(C1 c1, C1 c2) on C1:  c1.ID = {0}, c2.ID = {1}",
            c1.ID, c2.ID);
    }
}

public class F
{
    public void M1(C1 c)
    {
        Console.WriteLine("Instance method M1(C1 c) on F:  c.ID = {0}",
            c.ID);
    }

    public static void M3(C1 c)
    {
        Console.WriteLine("Static method M3(C1 c) on F:  c.ID = {0}", c.ID);
    }

    public static void M4(F f, C1 c)
    {
        Console.WriteLine("Static method M4(F f, C1 c) on F:  c.ID = {0}",
            c.ID);
    }
}

public class Example
{
    public static void Main()
    {
        C1 c1 = new C1(42);
        C1 c2 = new C1(1491);
        F f1 = new F();

        D d;

        // Instance method with one argument of type C1.
        MethodInfo cmi1 = typeof(C1).GetMethod("M1");
        // Instance method with no arguments.
        MethodInfo cmi2 = typeof(C1).GetMethod("M2");
        // Static method with one argument of type C1.
        MethodInfo cmi3 = typeof(C1).GetMethod("M3");
        // Static method with two arguments of type C1.
        MethodInfo cmi4 = typeof(C1).GetMethod("M4");

        // Instance method with one argument of type C1.
        MethodInfo fmi1 = typeof(F).GetMethod("M1");
        // Static method with one argument of type C1.
        MethodInfo fmi3 = typeof(F).GetMethod("M3");
        // Static method with an argument of type F and an argument
        // of type C1.
        MethodInfo fmi4 = typeof(F).GetMethod("M4");

        Console.WriteLine("\nAn instance method on any type, with an argument of type C1.");
        // D can represent any instance method that exactly matches its
        // signature. Methods on C1 and F are shown here.
        //
        d = (D)Delegate.CreateDelegate(typeof(D), c1, cmi1);
        d(c2);
        d = (D)Delegate.CreateDelegate(typeof(D), f1, fmi1);
        d(c2);

        Console.WriteLine("\nAn instance method on C1 with no arguments.");
        // D can represent an instance method on C1 that has no arguments;
        // in this case, the argument of D represents the hidden first
        // argument of any instance method. The delegate acts like a
        // static method, and an instance of C1 must be passed each time
        // it is invoked.
        //
        d = (D)Delegate.CreateDelegate(typeof(D), null, cmi2);
        d(c1);

        Console.WriteLine("\nA static method on any type, with an argument of type C1.");
        // D can represent any static method with the same signature.
        // Methods on F and C1 are shown here.
        //
        d = (D)Delegate.CreateDelegate(typeof(D), null, cmi3);
        d(c1);
        d = (D)Delegate.CreateDelegate(typeof(D), null, fmi3);
        d(c1);

        Console.WriteLine("\nA static method on any type, with an argument of");
        Console.WriteLine("    that type and an argument of type C1.");
        // D can represent any static method with one argument of the
        // type the method belongs and a second argument of type C1.
        // In this case, the method is closed over the instance of
        // supplied for the its first argument, and acts like an instance
        // method. Methods on F and C1 are shown here.
        //
        d = (D)Delegate.CreateDelegate(typeof(D), c1, cmi4);
        d(c2);
        Delegate test =
            Delegate.CreateDelegate(typeof(D), f1, fmi4, false);

        // This final example specifies false for throwOnBindFailure
        // in the call to CreateDelegate, so the variable 'test'
        // contains Nothing if the method fails to bind (for
        // example, if fmi4 happened to represent a method of
        // some class other than F).
        //
        if (test != null)
        {
            d = (D)test;
            d(c2);
        }
    }
}

/* This code example produces the following output:

An instance method on any type, with an argument of type C1.
Instance method M1(C1 c) on C1:  this.id = 42, c.ID = 1491
Instance method M1(C1 c) on F:  c.ID = 1491

An instance method on C1 with no arguments.
Instance method M2() on C1:  this.id = 42

A static method on any type, with an argument of type C1.
Static method M3(C1 c) on C1:  c.ID = 42
Static method M3(C1 c) on F:  c.ID = 42

A static method on any type, with an argument of
    that type and an argument of type C1.
Static method M4(C1 c1, C1 c2) on C1:  c1.ID = 42, c2.ID = 1491
Static method M4(F f, C1 c) on F:  c.ID = 1491
*/
open System

// Declare two sample classes, C and F. Class C has an ID
// property so instances can be identified.
type C(id) =
    member _.ID = id 

    member _.M1(c: C) =
        printfn $"Instance method M1(C c) on C:  this.id = {id}, c.ID = {c.ID}"

    member _.M2() =
        printfn $"Instance method M2() on C:  this.id = {id}"

    static member M3(c: C) =
        printfn $"Static method M3(C c) on C:  c.ID = {c.ID}"

    static member M4(c1: C, c2: C) =
        printfn $"Static method M4(C c1, C c2) on C:  c1.ID = {c1.ID}, c2.ID = {c2.ID}"

// Declare a delegate type. The object of this code example
// is to show all the methods this delegate can bind to.
type D = delegate of C -> unit


type F() =
    member _.M1(c: C) =
        printfn $"Instance method M1(C c) on F:  c.ID = {c.ID}"

    member _.M3(c: C) =
        printfn $"Static method M3(C c) on F:  c.ID = {c.ID}"

    member _.M4(f: F, c: C) =
        printfn $"Static method M4(F f, C c) on F:  c.ID = {c.ID}"

[<EntryPoint>]
let main _ =
    let c1 = C 42
    let c2 = C 1491
    let f1 = F()

    // Instance method with one argument of type C.
    let cmi1 = typeof<C>.GetMethod "M1"
    // Instance method with no arguments.
    let cmi2 = typeof<C>.GetMethod "M2"
    // Static method with one argument of type C.
    let cmi3 = typeof<C>.GetMethod "M3"
    // Static method with two arguments of type C.
    let cmi4 = typeof<C>.GetMethod "M4"

    // Instance method with one argument of type C.
    let fmi1 = typeof<F>.GetMethod "M1"
    // Static method with one argument of type C.
    let fmi3 = typeof<F>.GetMethod "M3"
    // Static method with an argument of type F and an argument
    // of type C.
    let fmi4 = typeof<F>.GetMethod "M4"

    printfn "\nAn instance method on any type, with an argument of type C."
    // D can represent any instance method that exactly matches its
    // signature. Methods on C and F are shown here.
    let d = Delegate.CreateDelegate(typeof<D>, c1, cmi1) :?> D
    d.Invoke c2
    let d =  Delegate.CreateDelegate(typeof<D>, f1, fmi1) :?> D
    d.Invoke c2

    Console.WriteLine("\nAn instance method on C with no arguments.")
    // D can represent an instance method on C that has no arguments
    // in this case, the argument of D represents the hidden first
    // argument of any instance method. The delegate acts like a
    // static method, and an instance of C must be passed each time
    // it is invoked.
    let d = Delegate.CreateDelegate(typeof<D>, null, cmi2) :?> D
    d.Invoke c1

    printfn "\nA static method on any type, with an argument of type C."
    // D can represent any static method with the same signature.
    // Methods on F and C are shown here.
    let d = Delegate.CreateDelegate(typeof<D>, null, cmi3) :?> D
    d.Invoke c1
    let d = Delegate.CreateDelegate(typeof<D>, null, fmi3) :?> D
    d.Invoke c1

    printfn "\nA static method on any type, with an argument of"
    printfn "    that type and an argument of type C."
    // D can represent any static method with one argument of the
    // type the method belongs and a second argument of type C.
    // In this case, the method is closed over the instance of
    // supplied for the its first argument, and acts like an instance
    // method. Methods on F and C are shown here.
    let d = Delegate.CreateDelegate(typeof<D>, c1, cmi4) :?> D
    d.Invoke c2
    let test =
        Delegate.CreateDelegate(typeof<D>, f1, fmi4, false)

    // This final example specifies false for throwOnBindFailure
    // in the call to CreateDelegate, so the variable 'test'
    // contains Nothing if the method fails to bind (for
    // example, if fmi4 happened to represent a method of
    // some class other than F).
    match test with
    | :? D as d ->
        d.Invoke c2
    | _ -> ()
    0

// This code example produces the following output:
//     An instance method on any type, with an argument of type C.
//     Instance method M1(C c) on C:  this.id = 42, c.ID = 1491
//     Instance method M1(C c) on F:  c.ID = 1491
//    
//     An instance method on C with no arguments.
//     Instance method M2() on C:  this.id = 42
//    
//     A static method on any type, with an argument of type C.
//     Static method M3(C c) on C:  c.ID = 42
//     Static method M3(C c) on F:  c.ID = 42
//    
//     A static method on any type, with an argument of
//         that type and an argument of type C.
//     Static method M4(C c1, C c2) on C:  c1.ID = 42, c2.ID = 1491
//     Static method M4(F f, C c) on F:  c.ID = 1491
Imports System.Reflection
Imports System.Security.Permissions

' Declare a delegate type. The object of this code example
' is to show all the methods this delegate can bind to.
'
Public Delegate Sub D(ByVal c As C) 

' Declare two sample classes, C and F. Class C has an ID
' property so instances can be identified.
'
Public Class C

    Private _id As Integer

    Public ReadOnly Property ID() As Integer 
        Get
            Return _id
        End Get
    End Property

    Public Sub New(ByVal newId As Integer) 
        Me._id = newId
    End Sub
    
    Public Sub M1(ByVal c As C) 
        Console.WriteLine("Instance method M1(c As C) on C:  this.id = {0}, c.ID = {1}", _
            Me.id, c.ID)
    End Sub
    
    Public Sub M2() 
        Console.WriteLine("Instance method M2() on C:  this.id = {0}", Me.id)
    End Sub
    
    Public Shared Sub M3(ByVal c As C) 
        Console.WriteLine("Shared method M3(c As C) on C:  c.ID = {0}", c.ID)
    End Sub
    
    Public Shared Sub M4(ByVal c1 As C, ByVal c2 As C) 
        Console.WriteLine("Shared method M4(c1 As C, c2 As C) on C:  c1.ID = {0}, c2.ID = {1}", _
            c1.ID, c2.ID)
    End Sub
End Class


Public Class F
    
    Public Sub M1(ByVal c As C) 
        Console.WriteLine("Instance method M1(c As C) on F:  c.ID = {0}", c.ID)
    End Sub
    
    Public Shared Sub M3(ByVal c As C) 
        Console.WriteLine("Shared method M3(c As C) on F:  c.ID = {0}", c.ID)
    End Sub
    
    Public Shared Sub M4(ByVal f As F, ByVal c As C) 
        Console.WriteLine("Shared method M4(f As F, c As C) on F:  c.ID = {0}", c.ID)
    End Sub
End Class

Public Class Example5

    Public Shared Sub Main()

        Dim c1 As New C(42)
        Dim c2 As New C(1491)
        Dim f1 As New F()

        Dim d As D

        ' Instance method with one argument of type C.
        Dim cmi1 As MethodInfo = GetType(C).GetMethod("M1")
        ' Instance method with no arguments.
        Dim cmi2 As MethodInfo = GetType(C).GetMethod("M2")
        ' Shared method with one argument of type C.
        Dim cmi3 As MethodInfo = GetType(C).GetMethod("M3")
        ' Shared method with two arguments of type C.
        Dim cmi4 As MethodInfo = GetType(C).GetMethod("M4")

        ' Instance method with one argument of type C.
        Dim fmi1 As MethodInfo = GetType(F).GetMethod("M1")
        ' Shared method with one argument of type C.
        Dim fmi3 As MethodInfo = GetType(F).GetMethod("M3")
        ' Shared method with an argument of type F and an 
        ' argument of type C.
        Dim fmi4 As MethodInfo = GetType(F).GetMethod("M4")

        Console.WriteLine(vbLf & "An instance method on any type, with an argument of type C.")
        ' D can represent any instance method that exactly matches its
        ' signature. Methods on C and F are shown here.
        '
        d = CType([Delegate].CreateDelegate(GetType(D), c1, cmi1), D)
        d(c2)
        d = CType([Delegate].CreateDelegate(GetType(D), f1, fmi1), D)
        d(c2)

        Console.WriteLine(vbLf & "An instance method on C with no arguments.")
        ' D can represent an instance method on C that has no arguments;
        ' in this case, the argument of D represents the hidden first
        ' argument of any instance method. The delegate acts like a 
        ' Shared method, and an instance of C must be passed each time
        ' it is invoked.
        '
        d = CType([Delegate].CreateDelegate(GetType(D), Nothing, cmi2), D)
        d(c1)

        Console.WriteLine(vbLf & "A Shared method on any type, with an argument of type C.")
        ' D can represent any Shared method with the same signature.
        ' Methods on F and C are shown here.
        '
        d = CType([Delegate].CreateDelegate(GetType(D), Nothing, cmi3), D)
        d(c1)
        d = CType([Delegate].CreateDelegate(GetType(D), Nothing, fmi3), D)
        d(c1)

        Console.WriteLine(vbLf & "A Shared method on any type, with an argument of")
        Console.WriteLine("    that type and an argument of type C.")
        ' D can represent any Shared method with one argument of the
        ' type the method belongs and a second argument of type C.
        ' In this case, the method is closed over the instance of
        ' supplied for the its first argument, and acts like an instance
        ' method. Methods on F and C are shown here.
        '
        d = CType([Delegate].CreateDelegate(GetType(D), c1, cmi4), D)
        d(c2)
        Dim test As [Delegate] =
            [Delegate].CreateDelegate(GetType(D), f1, fmi4, False)

        ' This final example specifies False for throwOnBindFailure 
        ' in the call to CreateDelegate, so the variable 'test'
        ' contains Nothing if the method fails to bind (for 
        ' example, if fmi4 happened to represent a method of  
        ' some class other than F).
        '
        If test IsNot Nothing Then
            d = CType(test, D)
            d(c2)
        End If

    End Sub
End Class

' This code example produces the following output:
'
'An instance method on any type, with an argument of type C.
'Instance method M1(c As C) on C:  this.id = 42, c.ID = 1491
'Instance method M1(c As C) on F:  c.ID = 1491
'
'An instance method on C with no arguments.
'Instance method M2() on C:  this.id = 42
'
'A Shared method on any type, with an argument of type C.
'Shared method M3(c As C) on C:  c.ID = 42
'Shared method M3(c As C) on F:  c.ID = 42
'
'A Shared method on any type, with an argument of
'    that type and an argument of type C.
'Shared method M4(c1 As C, c2 As C) on C:  c1.ID = 42, c2.ID = 1491
'Shared method M4(f As F, c As C) on F:  c.ID = 1491
'

호환되는 매개 변수 형식 및 반환 형식

이 메서드 오버로드를 사용하여 만든 대리자의 매개 변수 형식 및 반환 형식은 대리자가 나타내는 메서드의 매개 변수 형식 및 반환 형식과 호환되어야 합니다. 형식은 정확히 일치할 필요가 없습니다.

대리자 매개 변수의 형식이 메서드 매개 변수의 형식보다 제한적인 경우 대리자의 매개 변수는 메서드의 해당 매개 변수와 호환됩니다. 이 경우 대리자로 전달된 인수를 안전하게 메서드로 전달할 수 있습니다.

마찬가지로 메서드의 반환 형식이 대리자의 반환 형식보다 제한적인 경우 대리자의 반환 형식은 메서드의 반환 형식과 호환됩니다. 이 경우 메서드의 반환 값을 안전하게 대리자의 반환 형식으로 캐스팅할 수 있습니다.

예를 들어 형식의 매개 변수와 반환 형식이 있는 대리자는 형식 HashtableObject 매개 변수와 형식 Object 의 반환 값 Hashtable이 있는 메서드를 나타낼 수 있습니다.

대리자가 나타낼 수 있는 메서드 결정

오버로드에서 제공하는 CreateDelegate(Type, Object, MethodInfo) 유연성을 생각하는 또 다른 유용한 방법은 지정된 대리자가 메서드 시그니처와 메서드 종류(정적 및 인스턴스)의 네 가지 조합을 나타낼 수 있다는 것입니다. 하나의 인수가 있는 대리자 형식 D 을 고려합니다 C. 다음은 모든 경우에 일치해야 하므로 반환 형식을 무시하고 메서드가 나타낼 수 있는 방법을 D 설명합니다.

  • D 는 인스턴스 메서드가 속한 형식에 관계없이 정확히 하나의 형식 C인수가 있는 인스턴스 메서드를 나타낼 수 있습니다. 호출 firstArgument 될 때 CreateDelegate 형식 method 의 인스턴스가 속하며 결과 대리자는 해당 인스턴스에 대해 닫혀 있다고 합니다. (Null 참조인 D 경우 firstArgument null 참조를 통해 닫을 수도 있습니다.)

  • D 는 인수가 없는 인스턴스 메서드를 C 나타낼 수 있습니다. CreateDelegate 호출 firstArgument 되는 경우 null 참조입니다. 결과 대리자는 열린 인스턴스 메서드를 나타내며 호출될 때마다 인스턴스 C 를 제공해야 합니다.

  • D 는 형식의 인수 하나를 사용하는 정적 메서드를 나타낼 수 있으며 해당 메서드는 모든 형식 C에 속할 수 있습니다. CreateDelegate 호출 firstArgument 되는 경우 null 참조입니다. 결과 대리자는 열린 정적 메서드를 나타내며 호출될 때마다 인스턴스 C 를 제공해야 합니다.

  • D 는 형식에 속하고 형식과 형식 FF 두 인수가 있는 정적 메서드를 나타낼 수 있습니다 C. CreateDelegate 호출 firstArgument 되는 경우는 .의 F인스턴스입니다. 결과 대리자는 해당 인스턴스 F에 대해 닫혀 있는 정적 메서드를 나타냅니다. 형식이 동일한 경우 FC 정적 메서드에는 해당 형식의 두 인수가 있습니다. (이 경우 D null 참조인 경우 firstArgument null 참조를 통해 닫힙니다.)