Delegate,Action,Func,匿名方法,匿名委托,事件 (转载)

一、委托Delegate

一般的方法(Method)中,我们的参数总是string,int,DateTime...这些基本的数据类型(或者没有参数),比如

publicvoid HelloWorld()
{
    Console.WriteLine("Hello World!");
}
publicvoid HelloWorld(string name)
{
    Console.WriteLine("Hello ,{0}!", name);
}

但是有些时候,我们希望把一个方法本身当做参数传递给另一个方法,比如

myObject.callMethod(HelloWorld);

在没有委托之前,这是一件极困难的事情,委托出现以后,这就是一件很容易的事情了,简单点讲:委托就是一种能把方法当做参数来使用的类型--当然这个定义跟官方的解释比起来极不严密,但易于理解

要点:
1.委托是一种类型(跟string,int,double...一样是.net的一种基本类型)
2.委托的定义必须与最终被调用的方法保持签名一致

比如:下面代码中的

delegate void D1(); 与 static void HelloWorld1(),我们抛开前面的类型关键字delegate与static,他们的签名都是void X()
void D2(string myName);与void HelloWorld2(string name); void HelloWorld3(string name);它们的签名格式都是 void X(string Y)

3.委托的好处之一在于可以保持签名格式不变的情况下,动态调用不同的处理逻辑(即不同的方法)

想想系统控件中的Button类,系统并不知道按钮按下去时到底会执行怎么样的逻辑(点击后的处理,每个项目可能都不一样,完全由需求决定),但是我们知道每个Button都有一个Click(object sender, EventArgs e)这样的东东,没错,就是委托(当然封装成了另一种衍生类型event),就是这种设计保证了统一的格式,不管你实际开发中想如何处理点击后的逻辑,只要按这个统一的签名来就行了
完整代码演示:

using System;
namespace ActionStudy
{
    class Program
    {
      
        delegatevoid D1();
        delegatevoid D2(string myName);

staticvoid Main(string[] args)
        {
            D1 d1 =new D1(HelloWorld1);
            d1();

D2 d2 =new D2(HelloWorld2);
            d2("Jimmy");

d2 =new D2(HelloWorld3);
            d2("杨俊明");

Console.Read();

}

staticvoid HelloWorld1()
        {
            Console.WriteLine("Hello World!");
        }

staticvoid HelloWorld2(string name)
        {
            Console.WriteLine("Hello,{0}!", name);
        }

staticvoid HelloWorld3(string name)
        {
            Console.WriteLine("你好,{0}!", name);
        }
    }
}

二 、匿名方法(.net2.0开始支持)

在“一、委托Delegate”的演示代码中,我们看到委托调用方法前,至少得先定义一个签名相同的方法,然后才能由委托调用(哪怕是只有一行代码的方法),好象有点烦哦,想偷懒,ok,没问题

using System;
namespace ActionStudy
{
    class Program
    {

delegatevoid D1();
        delegatevoid D2(string myName);

staticvoid Main(string[] args)
        {
            D1 d1 =delegate
            {
                Console.WriteLine("Hello World!");
            };
            d1();

D2 d2 =delegate(string name)
            {
                Console.WriteLine("Hello,{0}!", name);
            };

d2("Jimmy");

d2 =delegate(string name)
            {
                Console.WriteLine("你好,{0}!", name);
            };

d2("杨俊明");

Console.Read();

}
    }
}

运行效果完全相同,只是省去了方法的单独定义部分

到了.net 3.0这种偷懒的作风更夸张,看下面的代码(利用了Lambda表达式)

using System;
namespace ActionStudy
{
    class Program
    {

delegatevoid D1();
        delegatevoid D2(string myName);

staticvoid Main(string[] args)
        {

D1 d1 = () => { Console.WriteLine("Hello World!"); };
            d1();

D2 d2 = (string name) => { Console.WriteLine("Hello,{0}!", name); };
            d2("Jimmy");

d2 = (string name) => { Console.WriteLine("你好,{0}!", name); };
            d2("杨俊明");

Console.Read();

}
    }
}

运行效果仍然没变,初次接触者可能感觉很怪,其实我也觉得怪,不过很多大牛们都喜欢这样用,所以至少还是要能看得懂,否则别人会说"你 Out了" :)
三、Action

Action的本质就是委托,看它的定义:

namespace System
{
    // 摘要:
    //     Encapsulates a method that takes no parameters and does not return a value.
    publicdelegatevoid Action();
}

namespace System
{
    // 摘要:
    //     Encapsulates a method that takes a single parameter and does not return a
    //     value.
    //
    // 参数:
    //   obj:
    //     The parameter of the method that this delegate encapsulates.
    //
    // 类型参数:
    //   T:
    //     The type of the parameter of the method that this delegate encapsulates.
    publicdelegatevoid Action<T>(T obj);
}

当然,还有Action<T1,T2>乃至Action<T1,T2,T3,T4>参数个数从2到4的类型,不过定义都差不多

简单点讲,Action是参数从0到4,返回类型为void(即没有返回值)的委托

using System;
namespace ActionStudy
{
    class Program
    {

static Action A1;
        static Action<string> A2;

staticvoid Main(string[] args)
        {
            A1 =new Action(HelloWorld1);
            A1();

A2 =new Action<string>(HelloWorld2);
            A2("Jimmy");

A2 = (string name) => { Console.WriteLine("你好,{0}!", name); };
            A2("杨俊明");

A2 =delegate(string name) { Console.WriteLine("我就是委托,{0} 你说对吗?", name); };
            A2("菩提树下的杨过");

Console.Read();

}

staticvoid HelloWorld1()
        {
            Console.WriteLine("Hello World!");
        }

staticvoid HelloWorld2(string name)
        {
            Console.WriteLine("Hello,{0}!", name);
        }

}

}

四、Func

Func其实也是一个"托"儿,呵呵,不过这个委托是有返回值的。看下定义就知道了:

namespace System
{
    // 摘要:
    //     Encapsulates a method that has no parameters and returns a value of the type
    //     specified by the TResult parameter.
    //
    // 类型参数:
    //   TResult:
    //     The type of the return value of the method that this delegate encapsulates.
    //
    // 返回结果:
    //     The return value of the method that this delegate encapsulates.
    publicdelegate TResult Func<TResult>();
}

namespace System
{
    // 摘要:
    //     Encapsulates a method that has one parameter and returns a value of the type
    //     specified by the TResult parameter.
    //
    // 参数:
    //   arg:
    //     The parameter of the method that this delegate encapsulates.
    //
    // 类型参数:
    //   T:
    //     The type of the parameter of the method that this delegate encapsulates.
    //
    //   TResult:
    //     The type of the return value of the method that this delegate encapsulates.
    //
    // 返回结果:
    //     The return value of the method that this delegate encapsulates.
    publicdelegate TResult Func<T, TResult>(T arg);
}

同Action类似,Func的参数从1到5个,有5个不同的重载版本
代码:

using System;
namespace ActionStudy
{
    class Program
    {
               
        static Func<string> F;
        static Func<DateTime, string> F2;

staticvoid Main(string[] args)
        {
            F =new Func<string>(HelloWorld1);
            Console.WriteLine(F());

F2 =new Func<DateTime, string>(HelloWorld2);
            Console.WriteLine(F2(DateTime.Now));

Console.Read();

}

staticstring HelloWorld1()
        {
            return"Hello World!";
        }

staticstring HelloWorld2(DateTime time)
        {
            returnstring.Format("Hello World,the time is {0}.", time);
        }
      
    }  
}

五、匿名委托

ok,如果你没有晕的话,再来看一下匿名委托,其实这也是一种偷懒的小伎俩而已
看代码说话:

//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;

这其实就是匿名委托的应用.

六、事件event

其实,这...还是个托儿!

我们来看下按钮Click事件的定义

// 摘要:
//     Occurs when the control is clicked.
publicevent EventHandler Click;

继续刨根问底,查看EventHandler的定义:

using System.Runtime.InteropServices;

namespace System
{
    // 摘要:
    //     Represents the method that will handle an event that has no event data.
    //
    // 参数:
    //   sender:
    //     The source of the event.
    //
    //   e:
    //     An System.EventArgs that contains no event data.
    [Serializable]
    [ComVisible(true)]
    publicdelegatevoid EventHandler(object sender, EventArgs e);
}

看到了吧,就是委托!

转载请注明来自菩提树下的杨过http://www.cnblogs.com/yjmyzz/archive/2009/11/23/1608818.html

转载于:https://www.cnblogs.com/xishi/p/3653235.html

Delegate,Action,Func,匿名方法,匿名委托,事件 (转载)相关推荐

  1. Delegate,Action,Func,匿名方法,匿名委托,事件

    一.委托Delegate 一般的方法(Method)中,我们的参数总是string,int,DateTime...这些基本的数据类型(或者没有参数),比如 [c-sharp] view plainco ...

  2. 匹夫细说C#:委托的简化语法,聊聊匿名方法和闭包

    0x00 前言 通过上一篇博客<匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的>的内容,我们实现了使用委托来构建我们自己的消息系统的过程.但是在日常的开发中,仍然有很多开发者因为 ...

  3. C# 从CIL代码了解委托,匿名方法,Lambda 表达式和闭包本质

    前言 C# 3.0 引入了 Lambda 表达式,程序员们很快就开始习惯并爱上这种简洁并极具表达力的函数式编程特性. 本着知其然,还要知其所以然的学习态度,笔者不禁想到了几个问题. (1)匿名函数(匿 ...

  4. java 匿名委托_委托,匿名方法,λ 表达式

    1.委托:委托本质上就是函数指针,但由于指针过于灵活,因此在很多语言中都采用了更加安全的替代类型,比如Delphi的对象方法和C#的委托.委托使得方法可以做为参数进行传递,极大的方便了程序的处理(事件 ...

  5. .NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法

    开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以, ...

  6. 第八节:语法总结(2)(匿名类、匿名方法、扩展方法)

    一. 匿名类 1. 传统的方式给类赋值,需要先建一个实体类→实例化→赋值,步骤很繁琐,在.Net 3.0时代,微软引入匿名类的概念,简化了代码编写,提高了开发效率.  匿名类的声明语法:  var o ...

  7. C#基础17:匿名方法与Lambda表达式

    前文:https://blog.csdn.net/Jaihk662/article/details/96895681(委托) 一.匿名方法 匿名方法:字面理解,没有名字(名字省略)的方法.在开发过程中 ...

  8. Unity学习(C#)——匿名方法(lambda)

    1.匿名方法 匿名方法本质上是一个方法,只是没有名字,任何使用委托变量的地方都可以使用匿名方法赋值 Func<int,int,int> plus=delegate(int arg1,int ...

  9. 雷林鹏分享:C# 匿名方法

    C# 匿名方法 我们已经提到过,委托是用于引用与其具有相同标签的方法.换句话说,您可以使用委托对象调用可由委托引用的方法. 匿名方法(Anonymous methods) 提供了一种传递代码块作为委托 ...

最新文章

  1. c语言大项目经验,C语言该学的地方(项目经验)
  2. Cissp-【第1章 安全和风险管理】-2020-12-03(1页-32页)
  3. python背包问题并行_python基于递归解决背包问题详解
  4. Beyond的歌里最多是唏嘘吗? - Python分词+词频
  5. http协议网络编程
  6. popwindow 焦点问题,物理返回键截获,软键盘监听问题
  7. SAP S/4HANA里如何创建Customer主数据以及执行后续处理
  8. Educational Codeforces Round 16 C. Magic Odd Square 矩阵构造
  9. GZIP pre-compression
  10. oracle数据库常用的语法与复合函数
  11. BugkuCTF-Reverse题逆向入门
  12. 如何从键盘键入字符串c语言scanf,输入字符串的格式要求 用scanf输入字符型数据时,输入的格式要注意什么?...
  13. Unity UGUI 屏幕适配
  14. python免费自学爬虫_看这里!免费python网络爬虫一站通
  15. Matlab fprintf
  16. 云知声开源全栈语音交互方案
  17. php 格林尼治标准时间,PHP函数第18款:返回格林威治标准时间MyDate
  18. 【LeetCode】799.香槟塔
  19. 产品策划五:App升级系统策划方案
  20. 简单创意思维导图绘制教程分享

热门文章

  1. Unity3D入门基础之游戏对象 (GameObject) 和组件 (Component) 的关系
  2. 分布式缓存DistributedCache的使用
  3. 建造者模式与原型模式/builder模式与prototype模式/创建型模式
  4. Mysql Federated Server 示例
  5. 企鹅帝国的疯狂反扑!
  6. Mybatis实现物理分页
  7. Linux扩展SWAP分区
  8. jdbc hibernate ibatis 操作Blob 和Clob类型字段(不断更新)
  9. 合成孔径成像算法与实现_声呐二维成像技术
  10. Win64 驱动内核编程-10.突破WIN7的PatchGuard