5

C#扫盲篇(三):Action和Func委托--实话实说

 3 years ago
source link: http://www.cnblogs.com/Mr-Worlf/p/14260069.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一、 基础定义

老王想找老张的老婆出去耍,但是一看,老张还在厨房煮饭。于是老王就对老张隔壁的淑芬说:“等下老张吃完饭出去喝茶,你就把前门晒的苞谷收了,老张从左门出,你就收右边的苞谷,我就知道从鸡舍进来。老张从右门出,你就收左墙的苞谷,我就从侧屋翻墙进来”。

在这个过程中,

  • 事件就是:”老张吃完饭去喝茶“
  • 委托就是:“把前门的苞谷收了”
  • 回调函数就是:“找老张的老婆去耍”
  • 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)当一个窗体中的数据变化时,与其关联的另外一个窗体中相应数据需要实时改变,可以使用委托对象调用第二个窗体中的相关方法实现。

五、总结

为了实现方法的参数化,提出了委托的概念,委托是一种引用方法的类型,即委托是方法的引用,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。大家在看的同时一定也要动手实践,这样才能把知识变成自己的体系。希望能给一些朋友捋捋思绪,形成自己的知识体系。

往期精彩:

首发自:【程序员不帅哥 】公众号

原文链接:https://mp.weixin.qq.com/s/LCPLjBmmbJwXBDWdi3SU1g

扫码关注,更多精彩内容及时获取,一起提高,一起加油

auiUJ3I.png!mobile


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK