System.Delegate.CreateDelegate メソッド
この記事では、この API のリファレンス ドキュメントへの補足的な解説を提供します。
メソッドは CreateDelegate 、指定した型のデリゲートを作成します。
CreateDelegate(Type, MethodInfo) メソッド
このメソッド のオーバーロードは、メソッド オーバーロードを呼び出し、次throwOnBindFailure
のようにCreateDelegate(Type, MethodInfo, Boolean)指定することとtrue
同じです。
例
このセクションには、2 つのコード例が含まれています。 最初の例では、このメソッド オーバーロードを使用して作成できる 2 種類のデリゲートを示します。インスタンス メソッドを使用して開き、静的メソッドで開きます。
2 番目のコード例では、互換性のあるパラメーター型と戻り値の型を示します。
例 1
次のコード例は、メソッドのこのオーバーロードを使用してデリゲートを作成する 2 つの方法を CreateDelegate 示しています。
Note
メソッドには 2 つのオーバーロードがあり、最初の CreateDelegate 引数は指定 MethodInfo しません。その機能は同じですが、1 つはバインドに失敗した場合にスローするかどうかを指定でき、もう 1 つは常にスローします。 このコード例では、両方のオーバーロードを使用します。
この例では、静的メソッドとインスタンス メソッドを持つクラスC
と、2 つのデリゲート型 D1
(インスタンスC
と文字列を受け取り、D2
文字列を受け取る) を宣言します。M2
M1
名前付きの Example
2 番目のクラスには、デリゲートを作成するコードが含まれています。
- インスタンス メソッド
M1
に対して、開いているインスタンス メソッドを表す型D1
のデリゲートが作成されます。 デリゲートが呼び出されたときにインスタンスを渡す必要があります。 - 静的メソッド
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
型の 1 つのパラメーターと戻りDerived
値の型Base
で名前が付けられた MyMethod
(Shared
Visual Basic の) メソッドがあります。 このコード例では、型のパラメーターと戻り値の型Derived
が 1 つの名前Example
のデリゲートも定義しますBase
。
このコード例では、名前付きの Example
デリゲートを使用してメソッド MyMethod
を表すことができることを示します。 メソッドは、次の理由でデリゲートにバインドできます。
- デリゲート () のパラメーター型は 、
Derived
() のパラメーター型よりも制限が厳しく、デリゲートMyMethod
のMyMethod
Base
引数を渡しても常に安全です。 - (
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) メソッド
これら 2 つのオーバーロードの機能は同じですが、1 つはバインドに失敗した場合にスローするかどうかを指定でき、もう 1 つは常にスローします。
デリゲート型とメソッドには互換性のある戻り値の型が必要です。 つまり、戻り値の型は、戻り値の method
型 type
に代入できる必要があります。
firstArgument
、これらのオーバーロードの 2 番目のパラメーターは、デリゲートが表すメソッドの最初の引数です。 firstArgument
指定すると、デリゲートが呼び出firstArgument
されるたびに渡されますmethod
。デリゲートにバインドされると言われ、デリゲートは最初の引数で閉じられると言われます。 if (static
Shared
Visual Basic の場合method
)、デリゲートの呼び出し時に指定された引数リストには、最初のパラメーターを除くすべてのパラメーターが含まれます。インスタンス メソッドの場合method
は、firstArgument
非表示のインスタンス パラメーター (C# または Me
Visual Basic で表されますthis
) に渡されます。
指定する場合 firstArgument
、最初の method
パラメーターは参照型であり、その型と firstArgument
互換性がある必要があります。
重要
is static
(Shared
Visual Basic の場合) とその最初のパラメーターが型Objectの場合method
、またはValueType値firstArgument
型にすることができます。 この場合 firstArgument
、自動的にボックス化されます。 自動ボックス化は、C# または Visual Basic 関数呼び出しの場合と同様に、他の引数では発生しません。
null 参照でmethod
インスタンス メソッドの場合firstArgument
、結果はデリゲート型type
のシグネチャと次のmethod
シグネチャに依存します。
- シグネチャに明示的に非表示の最初の
type
method
パラメーターが含まれている場合、デリゲートは開いているインスタンス メソッドを表すと言われます。 デリゲートが呼び出されると、引数リストの最初の引数が 、の非表示のインスタンス パラメーターmethod
に渡されます。 - シグネチャ
method
とtype
一致する (つまり、すべてのパラメーター型に互換性がある) 場合、デリゲートは null 参照で閉じられると言われます。 デリゲートの呼び出しは、null インスタンスでインスタンス メソッドを呼び出すことと似ていますが、これは特に便利なことではありません。
null 参照でmethod
静的な場合firstArgument
、結果はデリゲート型type
のシグネチャと次のmethod
シグネチャに依存します。
- シグネチャ
method
type
と一致する場合 (つまり、すべてのパラメーター型に互換性がある)、デリゲートはオープン静的メソッドを表すと言います。 これは、静的メソッドの最も一般的なケースです。 この場合、メソッドのオーバーロードを使用すると、パフォーマンスが CreateDelegate(Type, MethodInfo) 若干向上します。 - シグネチャが 2 番目の
type
パラメーターmethod
で始まり、残りのパラメーター型に互換性がある場合、デリゲートは null 参照で閉じられると言われます。 デリゲートが呼び出されると、最初のパラメーターmethod
に null 参照が渡されます。
例
次のコード例は、1 つのデリゲート型が表すことができるすべてのメソッドを示しています。インスタンス メソッドで閉じる、インスタンス メソッドで開く、静的メソッドで開く、静的メソッドで閉じるなどです。
このコード例では、2 つのクラスとF
、C
型の 1 つの引数を持つデリゲート型D
を定義しますC
。 クラスには一致する静的メソッドとインスタンス メソッドM1
があり、M4
M3
クラスC
には引数のないインスタンス メソッドM2
もあります。
名前付きの Example
3 番目のクラスには、デリゲートを作成するコードが含まれています。
- デリゲートは、型と型
C
F
のインスタンス メソッドM1
用に作成されます。各デリゲートは、それぞれの型のインスタンスで閉じられます。 型C
のメソッドM1
は、ID
バインドされたインスタンスと引数のプロパティを表示します。 - 型
C
のメソッドM2
に対してデリゲートが作成されます。 これは、デリゲートの引数がインスタンス メソッドの非表示の最初の引数を表す、開いているインスタンス デリゲートです。 このメソッドには他の引数はありません。 静的メソッドであるかのように呼び出されます。 - デリゲートは、型と型
C
F
の静的メソッドM3
用に作成されます。これらはオープン静的デリゲートです。 - 最後に、型と型
C
F
の静的メソッドM4
に対してデリゲートが作成されます。各メソッドは宣言型を最初の引数として持ち、型のインスタンスが指定されるため、デリゲートは最初の引数で閉じられます。 型C
のメソッドM4
は、ID
バインドされたインスタンスと引数のプロパティを表示します。
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
'
互換性のあるパラメーター型と戻り値の型
このメソッド オーバーロードを使用して作成されたデリゲートのパラメーター型と戻り値の型は、デリゲートが表すメソッドのパラメーター型と戻り値の型と互換性がある必要があります。型が正確に一致する必要はありません。
デリゲートのパラメーターにメソッドのパラメーターよりも限定的な型が指定された場合、両者のパラメーター間に型の互換性があると見なされます。これによって、デリゲートに渡された引数が、メソッドに対して安全に渡されることが保証されます。
同様に、メソッドの戻り値の型の制限がデリゲートの戻り値の型より多いと、メソッドの戻り値がデリゲートの戻り値の型に安全にキャストされることが保証されるため、デリゲートの戻り値の型とメソッドの戻り値の型には互換性があります。
たとえば、型のパラメーターと戻り値の型を持つデリゲートは、型 Hashtable の Object パラメーターと型 Object の戻り値 Hashtableを持つメソッドを表すことができます。
デリゲートが表すことができるメソッドを決定する
オーバーロードによって CreateDelegate(Type, Object, MethodInfo) 提供される柔軟性を考えるもう 1 つの便利な方法は、任意のデリゲートがメソッド シグネチャとメソッドの種類 (静的とインスタンス) の 4 つの異なる組み合わせを表すことができるということです。 型の 1 つの引数を持つデリゲート D
型について考えてみましょう C
。 次に、すべてのケースで一致する必要があるため、戻り値の型を無視して、メソッドが表すことができる方法 D
について説明します。
D
は、インスタンス メソッドが属する型に関係なく、型C
の引数を 1 つだけ持つ任意のインスタンス メソッドを表すことができます。 呼び出されると CreateDelegate 、firstArgument
型method
のインスタンスが属し、結果のデリゲートはそのインスタンス上で閉じられると言われます。 (単純に、D
null 参照の場合firstArgument
は null 参照で閉じることもできます)。D
は、引数を持たないインスタンス メソッドC
を表すことができます。 呼び出されると CreateDelegate 、firstArgument
null 参照になります。 結果のデリゲートは開いているインスタンス メソッドを表し、呼び出されるたびにインスタンスC
を指定する必要があります。D
は、型C
の 1 つの引数を受け取る静的メソッドを表し、そのメソッドは任意の型に属することができます。 呼び出されると CreateDelegate 、firstArgument
null 参照になります。 結果のデリゲートは、開いている静的メソッドを表し、呼び出されるたびにインスタンスC
を指定する必要があります。D
は、型に属し、型とC
型F
の 2 つの引数をF
持つ静的メソッドを表すことができます。 呼 CreateDelegate び出されると、firstArgument
のインスタンスF
になります。 結果のデリゲートは、そのインスタンスF
で閉じられている静的メソッドを表します。 同じ型の場合F
C
、静的メソッドにはその型の 2 つの引数があることに注意してください。 (この場合、D
null 参照の場合firstArgument
は null 参照で閉じられます)。
.NET
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示