C#扫盲篇(三):Action和Func委托--实话实说
一、基础定义
老王想找老张的老婆出去耍,但是一看,老张还在厨房煮饭。于是老王就对老张隔壁的淑芬说:“等下老张吃完饭出去喝茶,你就把前门晒的苞谷收了,老张从左门出,你就收右边的苞谷,我就知道从鸡舍进来。老张从右门出,你就收左墙的苞谷,我就从侧屋FQ进来”。
在这个过程中,
- 事件就是:”老张吃完饭去喝茶“
- 委托就是:“把前门的苞谷收了”
- 回调函数就是:“找老张的老婆去耍”
- sender就是:老张
- 事件句柄就是: 淑芬
- EventArgs就是事件参数 : 收左边的苞谷还是右边的苞谷
1.声明格式:
——用关键字“delegate”修饰委托
——委托的返回类型和参数要和被委托的方法保持一致例如:
public class TestClass
{
public delegate int delegateAction();
public event delegateAction OnActionEvent;
public delegateAction daNew;
}
2.委托和方法关联
在声明了委托和定义好方法之后,我们需要将委托和方法进行关联,这样委托才能知道自己要调用的是哪个方法。
//委托和方法关联
MyDelegate my = new MyDelegate(MyClass.Method1);
3. 委托调用方法
将委托和方法进行关联之后,我们就可以直接操作委托实例来进行方法的调用,调用方式和直接调用方法差不多。
//实例化委托的实例方法
MyClass c = new MyClass();
My my2 = new My(c.Methods);
my("Hello");
my2("Hello");
4. 效果
有了上面的使用之后,我们会发现委托基本都是根据具体方法来声明的,如果不同的方法有3个,4个或者更多的参数,显然,我们需要分别声明不同参数个数的委托,不经意间多了一道“声明委托”的门槛。于是,在.Net Framework3.5版本之后发布了.Net自带的内置委托Action和Func。我们不用再做“声明委托”的工作,直接可以使用。
5.Action委托
Action委托提供无参数、有参数方法,但不提供返回类型,具有Action、Action、Action<t1,t2>、Action<t1,t2,t3>……Action<t1,……t16>多达16个参数的形式,其中传入参数均采用泛型T,涵盖了几乎所有可能存在的无返回值的委托类型。<t1,t2><t1,t2,t3><t1,……t16>
6.Func委托
Func委托提供无参数、有参数方法,同时提供返回类型,具有Func、Func<t,tresult>……Func<t1,t2,t3……,tresult>17种类型重载,T1……T16为参数,Tresult为返回类型。
前面我们说,Action委托和Func委托不用再声明,便可直接使用,除了这一点,它们还支持匿名函数、lamda表达式形式。
7.Action委托与Func委托区别
看出Func与Action是类似的,唯一的区别就是,Func必须指定返回值的类型,使用方式与委托咱们自己使用委托变量是一样的,直接使用相应参数的Func或者Action声明变量,=或者+=挂载函数(方法即可)
这两个其实说白了就是系统定义好的Delegate,他有很多重载的方法,便于各种应用情况下的调用。他在系统的System命名空间下,因此全局可见。
二、匿名函数
如果你没有晕的话,再来看一下匿名委托,其实这也是一种偷懒的小伎俩而已
看代码说话:
//F = new Func<string>(HelloWorld1);
其实也可以简写成这样:
F = HelloWorld1;
//F2 = new Func<DateTime, string>(HelloWorld2);
其实也可以简写成这样
F2 = HelloWorld2;
方法直接赋值给委托,这二个类型不同吧???
没错,你会发现编译一样能通过,系统在编译时在背后自动帮我们加上了类似 “= new Func<...>”的东东,所以我们能偷懒一下下,这个就是匿名委托。
如果你细心的话,会发现我们在定义Button的Click处理事件时,通常是这样的:
this.button1.Click += new EventHandler(button1_Click);
但有时候我们也可以写成这样:
this.button1.Click += button1_Click;
这其实就是匿名委托的应用.
三、lamda表达式
//使用lambda 表达式
NoParameter noParameterNew1 = new NoParameter(
() => Console.WriteLine("我是:无参无返回值方法")
);
Parameter parameterNew1 = new Parameter(
(Para) => Para
);
四、Action委托实例
Action委托和Func委托的唯一区别就是没有返回类型,其他用法都一样,当不需要返回类型的时候,直接用Action委托。class Program
{
static void Main(string[] args)
{
string mid = ",mid";
Action<string> anonDel = delegate (string param)
{
param += mid;
param += " and this.";
Console.WriteLine(param);
};
anonDel += delegate (string t)
{
Console.WriteLine(t + System.Guid.NewGuid().ToString());
};
anonDel("www.webczw.com");
Console.ReadKey();
}
}
(1)服务器对象可以提供一个方法,客户端对象调用该方法为特定的事件注册回调方法。当事件发生时,服务器就会调用该回调函数。通常客户端对象实例化引用回调函数的委托,并将该委托对象作为参数传递。
(2)当一个窗体中的数据变化时,与其关联的另外一个窗体中相应数据需要实时改变,可以使用委托对象调用第二个窗体中的相关方法实现。
为了实现方法的参数化,提出了委托的概念,委托是一种引用方法的类型,即委托是方法的引用,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。大家在看的同时一定也要动手实践,这样才能把知识变成自己的体系。希望能给一些朋友捋捋思绪,形成自己的知识体系。
往期精彩:
- C#扫盲篇(一):反射机制--情真意切的说
- C#扫盲篇(二)依赖倒置•控制反转•依赖注入•面向接口编程--满腹经纶的说
- 利用COM组件实现对WORD书签各种操作大全,看这一篇就够了
- Entity Framework 更新失败,调试后发现是AsNoTracking的原因
- “生如蝼蚁,当立鸿鹄之志”|2020年终总结
首发自:【程序员不帅哥 】公众号
原文链接:https://mp.weixin.qq.com/s/LCPLjBmmbJwXBDWdi3SU1g
扫码关注,更多精彩内容及时获取,一起提高,一起加油