下面的代码示例演示可以使用此 CreateDelegate 方法重载创建委托的两种方式。
说明注意:
有两种 CreateDelegate 方法重载,它们指定 MethodInfo 但不指定第一个参数;其功能基本相同,不同之处在于一个允许您指定是否在绑定失败时引发异常,而另一个始终引发异常。此代码示例使用这两种重载。
此示例声明一个 C 类和两个委托类型,前者包含一个静态方法 M2 和一个实例方法 M1,后者包含接受 C 的一个实例和一个字符串的 D1 以及接受一个字符串的 D2。
另一个名为 Example 的类包含创建委托的代码。
为实例方法 M1 创建一个表示开放式实例方法的 D1 类型的委托。必须在调用委托时传递实例。
为静态方法 M2 创建一个表示开放式静态方法的 D2 类型的委托。
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) { 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 Example { 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 static 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! */
示例 2
下面的代码示例演示参数类型和返回类型的兼容性。
该代码示例定义名为 Base 的基类和从 Base 派生的名为 Derived 的类。派生类具有一个名为 MyMethod 的 static(在 Visual Basic 中为 Shared)方法,该方法具有一个 Base 类型的参数并且其返回类型为 Derived。该代码示例还定义名为 Example 的委托,该委托具有一个 Derived 类型的参数并且其返回类型为 Base。
该代码示例演示名为 Example 的委托可用于表示 MyMethod 方法。该方法可以绑定到该委托,原因是:
*委托的参数类型 (Derived) 的限制性强于 MyMethod 的参数类型 (Base),因此将委托的参数传递给 MyMethod 始终是安全的。
*MyMethod 的返回类型 (Derived) 的限制性强于委托的参数类型 (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 Example(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 covariance of parameter types and contravariance
// 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).
//
Example ex =
(Example) Delegate.CreateDelegate(typeof(Example), minfo);
// Execute MyMethod using the delegate Example.
//
Base b = ex(new Derived());
}
}