Delegate 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
表示一个委托,该委托是表示某一静态方法或某一类实例和该类的实例方法的数据结构。
public ref class Delegate abstract
public ref class Delegate abstract : ICloneable, System::Runtime::Serialization::ISerializable
public abstract class Delegate
public abstract class Delegate : ICloneable, System.Runtime.Serialization.ISerializable
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDual)]
[System.Serializable]
public abstract class Delegate : ICloneable, System.Runtime.Serialization.ISerializable
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDual)]
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class Delegate : ICloneable, System.Runtime.Serialization.ISerializable
type Delegate = class
type Delegate = class
interface ICloneable
interface ISerializable
[<System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDual)>]
[<System.Serializable>]
type Delegate = class
interface ICloneable
interface ISerializable
[<System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDual)>]
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type Delegate = class
interface ICloneable
interface ISerializable
Public MustInherit Class Delegate
Public MustInherit Class Delegate
Implements ICloneable, ISerializable
- 继承
-
Delegate
- 派生
- 属性
- 实现
示例
以下示例演示如何定义名为 的 myMethodDelegate
委托。 此委托的实例是为嵌套 mySampleClass
类的实例方法和静态方法创建的。 实例方法的委托需要 实例 mySampleClass
。 实例 mySampleClass
保存在名为 的 mySC
变量中。
using namespace System;
delegate String^ myMethodDelegate( // Declares a delegate for a method that takes in an int and returns a String.
int myInt );
// Defines some methods to which the delegate can point.
ref class mySampleClass
{
public:
// Defines an instance method.
String^ myStringMethod( int myInt )
{
if ( myInt > 0 )
return ("positive");
if ( myInt < 0 )
return ("negative");
return ("zero");
}
// Defines a static method.
static String^ mySignMethod( int myInt )
{
if ( myInt > 0 )
return ("+");
if ( myInt < 0 )
return ("-");
return ("");
}
};
int main()
{
// Creates one delegate for each method. For the instance method, an
// instance (mySC) must be supplied. For the static method, only the
// method name is needed.
mySampleClass^ mySC = gcnew mySampleClass;
myMethodDelegate^ myD1 = gcnew myMethodDelegate( mySC, &mySampleClass::myStringMethod );
myMethodDelegate^ myD2 = gcnew myMethodDelegate( mySampleClass::mySignMethod );
// Invokes the delegates.
Console::WriteLine( "{0} is {1}; use the sign \"{2}\".", 5, myD1( 5 ), myD2( 5 ) );
Console::WriteLine( "{0} is {1}; use the sign \"{2}\".", -3, myD1( -3 ), myD2( -3 ) );
Console::WriteLine( "{0} is {1}; use the sign \"{2}\".", 0, myD1( 0 ), myD2( 0 ) );
}
/*
This code produces the following output:
5 is positive; use the sign "+".
-3 is negative; use the sign "-".
0 is zero; use the sign "".
*/
using System;
public class SamplesDelegate {
// Declares a delegate for a method that takes in an int and returns a string.
public delegate string myMethodDelegate( int myInt );
// Defines some methods to which the delegate can point.
public class mySampleClass {
// Defines an instance method.
public string myStringMethod ( int myInt ) {
if ( myInt > 0 )
return( "positive" );
if ( myInt < 0 )
return( "negative" );
return ( "zero" );
}
// Defines a static method.
public static string mySignMethod ( int myInt ) {
if ( myInt > 0 )
return( "+" );
if ( myInt < 0 )
return( "-" );
return ( "" );
}
}
public static void Main() {
// Creates one delegate for each method. For the instance method, an
// instance (mySC) must be supplied. For the static method, use the
// class name.
mySampleClass mySC = new mySampleClass();
myMethodDelegate myD1 = new myMethodDelegate( mySC.myStringMethod );
myMethodDelegate myD2 = new myMethodDelegate( mySampleClass.mySignMethod );
// Invokes the delegates.
Console.WriteLine( "{0} is {1}; use the sign \"{2}\".", 5, myD1( 5 ), myD2( 5 ) );
Console.WriteLine( "{0} is {1}; use the sign \"{2}\".", -3, myD1( -3 ), myD2( -3 ) );
Console.WriteLine( "{0} is {1}; use the sign \"{2}\".", 0, myD1( 0 ), myD2( 0 ) );
}
}
/*
This code produces the following output:
5 is positive; use the sign "+".
-3 is negative; use the sign "-".
0 is zero; use the sign "".
*/
// Declares a delegate for a method that takes in an int and returns a string.
type MyMethodDelegate = delegate of int -> string
// Defines some methods to which the delegate can point.
type MySampleClass() =
// Defines an instance method.
member _.MyStringMethod(myInt) =
if myInt > 0 then "positive"
elif myInt < 0 then "negative"
else "zero"
// Defines a static method.
static member MySignMethod(myInt) =
if myInt > 0 then "+"
elif myInt < 0 then "-"
else ""
// Creates one delegate for each method. For the instance method, an
// instance (mySC) must be supplied. For the static method, use the
// class name.
let mySC = MySampleClass()
let myD1 = MyMethodDelegate mySC.MyStringMethod
let myD2 = MyMethodDelegate MySampleClass.MySignMethod
// Invokes the delegates.
printfn $"{5} is {myD1.Invoke 5} use the sign \"{myD2.Invoke 5}\"."
printfn $"{-3} is {myD1.Invoke -3} use the sign \"{myD2.Invoke -3}\"."
printfn $"{0} is {myD1.Invoke 0} use the sign \"{myD2.Invoke 0}\"."
// This code produces the following output:
// 5 is positive use the sign "+".
// -3 is negative use the sign "-".
// 0 is zero use the sign "".
Public Class SamplesDelegate
' Declares a delegate for a method that takes in an int and returns a String.
Delegate Function myMethodDelegate(myInt As Integer) As [String]
' Defines some methods to which the delegate can point.
Public Class mySampleClass
' Defines an instance method.
Public Function myStringMethod(myInt As Integer) As [String]
If myInt > 0 Then
Return "positive"
End If
If myInt < 0 Then
Return "negative"
End If
Return "zero"
End Function 'myStringMethod
' Defines a static method.
Public Shared Function mySignMethod(myInt As Integer) As [String]
If myInt > 0 Then
Return "+"
End If
If myInt < 0 Then
Return "-"
End If
Return ""
End Function 'mySignMethod
End Class
Public Shared Sub Main()
' Creates one delegate for each method. For the instance method, an
' instance (mySC) must be supplied. For the Shared method, the
' method name is qualified by the class name.
Dim mySC As New mySampleClass()
Dim myD1 As New myMethodDelegate(AddressOf mySC.myStringMethod)
Dim myD2 As New myMethodDelegate(AddressOf mySampleClass.mySignMethod)
' Invokes the delegates.
Console.WriteLine("{0} is {1}; use the sign ""{2}"".", 5, myD1(5), myD2(5))
Console.WriteLine("{0} is {1}; use the sign ""{2}"".", - 3, myD1(- 3), myD2(- 3))
Console.WriteLine("{0} is {1}; use the sign ""{2}"".", 0, myD1(0), myD2(0))
End Sub
End Class
'This code produces the following output:
'
'5 is positive; use the sign "+".
'-3 is negative; use the sign "-".
'0 is zero; use the sign "".
注解
类 Delegate 是委托类型的基类。 但是,只有系统和编译器才能从 Delegate 类或 MulticastDelegate 类显式派生。 也不允许从委托类型派生新类型。 类 Delegate 不被视为委托类型;它是用于派生委托类型的类。
大多数语言实现delegate
关键字 (keyword) ,这些语言的编译器能够派生自 MulticastDelegate 类;因此,用户应使用delegate
语言提供的关键字 (keyword) 。
注意
公共语言运行时为每个委托类型提供一个 Invoke
方法,其签名与委托相同。 不必从 C#、Visual Basic 或 Visual C++ 显式调用此方法,因为编译器会自动调用此方法。 Invoke
当想要查找委托类型的签名时,方法在反射中很有用。
公共语言运行时为每个委托类型 BeginInvoke
提供 和 EndInvoke
方法,以启用委托的异步调用。 有关这些方法的详细信息,请参阅 异步调用同步方法。
委托类型的声明将建立一个协定,该协定指定一个或多个方法的签名。 委托是引用的委托类型的实例:
类型的实例方法和可分配给该类型的目标对象。
类型的实例方法,在正式参数列表中公开了隐藏
this
参数。 该委托称为开放实例委托。静态方法。
一个静态方法和一个可分配给方法的第一个参数的目标对象。 据说代表在第一个论点上被关闭。
有关委托绑定的详细信息,请参阅 CreateDelegate(Type, Object, MethodInfo, Boolean) 方法重载。
当委托表示在其第一个参数上关闭的实例方法 (最常见的情况) 时,委托存储对方法入口点的引用和对名为 目标的对象的引用,该对象属于可分配给定义该方法的类型的类型。 当委托表示打开的实例方法时,它将存储对方法入口点的引用。 委托签名必须在其正式参数列表中包括隐藏 this
参数;在这种情况下,委托没有对目标对象的引用,并且必须在调用委托时提供目标对象。
当委托表示静态方法时,委托存储对方法入口点的引用。 当委托表示在其第一个参数上关闭的静态方法时,委托存储对方法入口点的引用和对可分配给方法第一个参数类型的目标对象的引用。 调用委托时,静态方法的第一个参数将接收目标对象。 第一个参数必须是引用类型。
委托的调用列表是一组有序的委托,其中列表的每个元素都完全调用委托表示的方法之一。 调用列表可以包含重复的方法。 在调用期间,将按照方法在调用列表中出现的顺序调用方法。 委托尝试调用其调用列表中的每种方法;重复项每次出现在调用列表中时都会调用一次。 委托是不可变的;创建后,委托的调用列表不会更改。
委托称为多播或可组合,因为委托可以调用一个或多个方法,并且可用于组合操作。
组合操作(如 Combine 和 Remove)不会更改现有委托。 相反,此类操作返回包含操作结果的新委托、未更改的委托或 null
。 当操作的结果是不引用至少一个方法的委托时,组合操作将返回 null
。 当请求的操作不起作用时,组合操作将返回未更改的委托。
注意
托管语言使用 Combine 和 Remove 方法来实现委托操作。 示例包括 AddHandler
Visual Basic 中的 和 RemoveHandler
语句,以及 C# 中委托类型的 += 和 -= 运算符。
从.NET Framework 4 开始,泛型委托类型可以具有变体类型参数。 逆变类型参数可用作委托的参数类型,而协变类型参数可用作返回类型。 此功能允许从同一泛型类型定义构造的泛型委托类型与赋值兼容(如果其类型参数是具有继承关系的引用类型),如 协变和逆变中所述。
注意
由于方差而与赋值兼容的泛型委托不一定是可组合的。 为了可组合,这些类型必须完全匹配。 例如,假设名为 的 Derived
类派生自名为 的 Base
类。 Visual Basic) 中 (Action(Of Base)
类型的Action<Base>
委托可以分配给 类型的Action<Derived>
变量,但无法组合这两个委托,因为这些类型不匹配。
如果调用的方法引发异常,该方法将停止执行,该异常将传递回委托的调用方,并且不会调用调用列表中的其余方法。 捕获调用方中的异常不会更改此行为。
当委托调用的方法的签名包含返回值时,委托将返回调用列表中最后一个元素的返回值。 当签名包含通过引用传递的参数时,参数的最终值是调用列表中按顺序执行并更新参数值的每个方法的结果。
与 C 中的委托最接近的等效项是函数指针。 委托可以表示静态方法或实例方法。 当委托表示实例方法时,委托不仅存储对方法入口点的引用,还存储对类实例的引用。 与函数指针不同,委托面向对象且类型安全。
构造函数
Delegate(Object, String) |
初始化一个委托,该委托对指定的类实例调用指定的实例方法。 |
Delegate(Type, String) |
初始化一个委托,该委托从指定的类调用指定的静态方法。 |
属性
Method |
获取委托所表示的方法。 |
Target |
获取类实例,当前委托将对其调用实例方法。 |
方法
运算符
Equality(Delegate, Delegate) |
确定指定的委托是否相等。 |
Inequality(Delegate, Delegate) |
确定指定的委托是否不相等。 |
扩展方法
GetMethodInfo(Delegate) |
获取指示指定委托表示的方法的对象。 |