委托)是一种定义方法签名的类型。 当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联。 您可以通过委托实例调用方法。
委托用于将方法作为参数传递给其他方法。 事件处理程序就是通过委托调用的方法。 您可以创建一个自定义方法,当发生特定事件时某个类(例如 Windows 控件)就可以调用您的方法。
委托
在C#中是一个语言级特性,而在Java语言中没有直接的对应,但是java利用反射即可实现委托!
Func和Action
Func是一种委托,这是在3.5
里面新增的,2.0里面我们使用委托是用Delegate,Func位于System.Core命名空间下,使用委托可以提升效率,例如在反射中使用就可以弥补反射所损失的性能。
Action<T>
和Func<T,TResult>
的功能是一样的,只是Action<T>
没有返回值,Func<T,TResult>
的最后一个参数为返回值。
委托具有以下特点:
委托和接口都允许类设计器分离类型声明和实现。 任何类)或结构)都能继承和实现给定的接口)。
可以为任何类上的方法创建委托),前提是该方法符合委托的方法签名。
接口引用或委托可由不了解实现该接口或委托方法的类的对象使用。
既然存在这些相似性,那么类设计器何时应使用委托,何时又该使用接口呢?
在以下情况下,请使用委托:
在以下情况下,请使用接口:
IComparable) 或泛型版本 IComparable) 就是一个使用单一方法接口而不使用委托的很好的示例。 IComparable 声明 CompareTo) 方法,该方法返回一个整数,指定相同类型的两个对象之间的小于、等于或大于关系。 IComparable 可用作排序算法的基础。 虽然将委托比较方法用作排序算法的基础是有效的,但是并不理想。 因为进行比较的能力属于类,而比较算法不会在运行时改变,所以单一方法接口是理想的。
C# 1.0
及更高版本中,可以按以下示例所示声明委托。
// Declare a delegate.
delegate void Del(string str);
// Declare a method with the same signature as the delegate.
static void Notify(string name)
{
Console.WriteLine("Notification received for: {0}", name);
}
实例化
// Create an instance of the delegate.
Del del1 = new Del(Notify);
C# 2.0
提供了更简单的方法来编写上面的声明,如以下示例所示。
// C# 2.0 provides a simpler way to declare an instance of Del.
Del del2 = Notify;
C# 2.0
及更高版本中,还可以使用匿名方法来声明和初始化委托),如以下示例所示。
// Instantiate Del by using an anonymous method.
Del del3 = delegate(string name)
{ Console.WriteLine("Notification received for: {0}", name); };
C# 3.0
及更高版本中,还可以使用 Lambda 表达式来声明和实例化委托,如以下示例所示。
// Instantiate Del by using a lambda expression.
Del del4 = name => { Console.WriteLine("Notification received for: {0}", name); };
C# 3.5
里面新增Func
和Action
public static void threadRun2(Dispatcher dispatcher, Func<string> tFunc, Action<string> mainAction)
{
new Thread(o =>
{
string result = tFunc();
_ = dispatcher.Invoke(mainAction, result);
}
).Start();
}