一、委托的基本的写法internalclassPRogram
{privatestaticvoidMain(string[] args)
{
ChainDelegate();
Console.ReadKey();
}publicstaticvoidChainDelegate()
{//创建委托Feedback feedbackToConsole =newFeedback(FeedbackToConsole);
Feedback feedbackToMsBox=newFeedback(FeedbackToMsBox);//单个委托feedbackToConsole(1);
feedbackToMsBox(2);//委托链Feedback fbChain =null;
fbChain+=feedbackToConsole;
fbChain+=feedbackToMsBox;
fbChain(3);
}publicstaticvoidFeedbackToConsole(Int32 value)
{
Console.WriteLine(string.Concat("FeedbackToConsole->", value));
}publicstaticvoidFeedbackToMsBox(Int32 value)
{
Console.WriteLine(string.Concat("FeedbackToMsBox->", value));
}
}//定义一个委托internaldelegatevoidFeedback(Int32 value);
View Code
知识点:
1.定义delegate:delegate void Feedbakc(Int32 value)
delegate是关键字void返回值(这里可以定义各种返回值,包括泛型)Int32 value定义了输入的参数 2.定义回调函数FeedbackToConsole, FeedbackToMsBox
回调的函数的输入参数类型和个数要和定义的委托完全一样返回值是引用类型要遵守协变和逆变(这里可以看我转载的泛型3),值类型不用遵守遵守协变和逆变。3.创建委托 var feedbackToConsole=new Feedback(FeedbackToConsole)
用new关键字来创建委托参数是你的回调函数(要求看第2点)4.调用委托
feedbackToConsole(1)
feedbackToConsole.Invoke(1)
当创建好委托以后,所对应对象名(feedbackToConsole)就相当于委托的函数(FeedbackToConsole)。5.委托链
Feed fbChain=null;
fbChain+=feedbackToConsole;fbChain=(Feedback)Delegate.Combine(fbChain,feedbackToConsole);
fbChain+=feedbackToMsBox; fbChain=(Feedback)Delegate.Combine(fbChain,feedbackToMsBox);
有两种写法都列出来了,我喜欢第一种,比较简单和直接。委托链的调用和调用单个一样 fbChain(3)委托链的调用循序和绑定上去的循序一致(这里先调用feedbackToConsole,再调用feedbackToMsBox)6.移除委托链中的数据(补充)
fbChain -= feedbackToConsole fbChain=(Feedback)Delegate.Remove(fbChain,feedbackToConsole);
二、委托和Lamda表达式Feedback fd1 =newFeedback(i =>{
Console.WriteLine(i);
});
我们这样用Lamda表达式直接代替了回调函数,如果回调函数不是多个地方使用的话,我个人是比较喜欢这样的写法,而且我会写成:
Feedback fd1 =newFeedback(Console.WriteLine);
这块需要大家对Lamda表达式有一定的理解。
三、泛型委托 1.泛型委托和泛型接口一样,是有协变和逆变的(这里可以看我转载的泛型3)
2.泛型委托我们自己一般是不需要去创建的,因为C#自己提供了两种:
Action<T,......> :只带有输入参数的泛型委托(有N个重载)
Func<in TInput,......out TOutput> : 带输入参数和返回值的泛型委托(有N个重载)
3.关于EvenHandler<T>可以看一下【C#】事件