C#委托与事件--简单笔记

委托

简单记录点东西 适合似懂非懂的朋友看看
委托类型用来定义和响应应用程序中的回调。
借此能够设计各类有面向对象特性的代码模式。下面要说的事件在我看来就是委托的一种实现,再深一步讲,利用委托加事件,是否是能够构建各类所谓的管道框架。
ASP.NET WebAPI的管道模型,整个消息处理管道是经过一组有序的HttpMessagHandler “首尾相连”而成,具体实现“串联”的是经过DelegatingHandler这个类型来完成的。便是一组委托链html

最精华的内容您已看完框架

委托定义 public delegate int DeleName(int x);
名称
参数
返回值函数

一、委托简单示例

DeleName del = M1;
 public int  M1(int i)
 {
       ...
  }

入门理解1:委托是方法的类型,即委托=class,方法=new class()设计

上面的方法名称M1只起到传递做用时,能够用匿名委托代替:code

DeleName del = delegate (int i)
 {
      ...
 };

除了用匿名委托,还能够用lamda表达式进行代替:htm

DeleName del =  (int i)=>
 {
      ...
 };

在这里也能看出lamda本质就是委托

二、泛型委托

public delegate void MyGenericDelegate1<T>(T arg);
 public delegate int MyGenericDelegate2<T,M>(T arg,M name);

  MyGenericDelegate1<int> intTarget = new MyGenericDelegate<int>(IntTarget);
  static void IntTarget(int arg) => Console.WriteLine($"IntTarget--> {++arg}");
  
  MyGenericDelegate2<int,string> intTarget1 = (int arg,string name) =>
  {
        return 1;
   };

好处:封装为了复用对象

看下上面两个委托的命名:MyGenericDelegate1 MyGenericDelegate2 纯粹为了取名而取名,此时咱们能够不本身取名。
怎么作呢,C#自己提供了两个泛型委托能够给咱们使用,且可知足大多数场景。blog

三、泛型Action<> 和 Func<> 委托

(可指向至多传递16个参数的方法)

Action<>:无返回值: 定义 public delegate void Action<...>事件

public static void Show()
        {
            // 使用Action<>委托来指向 DisplayMessage()
            Action<string, ConsoleColor, int> actionTarget = new Action<string, ConsoleColor, int>(DisplayMessage);
            actionTarget("actionTarget", ConsoleColor.Red, 5);
        }

        // Action<> 委托的一个目标
        private static void DisplayMessage(string msg, ConsoleColor txtColor, int printCount)
        {
            ...
        }

Func<>:有返回值 public delegate TResult Func<..., out TResult> TResult:返回值类型get

Func<int, int, int> funcTarget = new Func<int, int, int>(Add);
 
 funcTarget(1, 2);
    
 static int Add(int x, int y) => x + y;

若是你以为一个具备自定义名称的委托更有助于捕获问题范畴,那么构建自定义委托不过就是一行代码的事儿。

注:Linq中就大量的用到了 Action<> 和 Func<>。

四、事件

最简单的说法是:能够把事件当作是委托的一个实例。委托比做类:它定义了函数的签名(接受什么类型的参数 返回什么类型的值)事件比做委托new出来的一个实例,是具备该委托签名的具体函数。固然事件和实例也是有区别的:
一、事件这个东西 能容纳不少个具体的函数(经过+= -= 增长删除)。
二、事件有event关键字起到了保护做用不容许改变事件的引用。即在声明事件的类外部不能用=对事件对象赋值

直接看看代码

public delegate void HelloWorldDelegate(string name);

public class HelloWorldClass2
    {
        public event HelloWorldDelegate del;//!!!!event修饰了委托对象
        public void HelloWorld(string name)
        {
            //del = (n) => { Console.WriteLine(n); };//在声明事件的类内部能够用=直接定义事件的引用(赋值)
            del(name);
        }
    }

 class Program
    { 
        static void Main(string[] args)
        { 
            HelloWorldClass2 h2 = new HelloWorldClass2();
            //h2.del = ByEnglish;//不容许改变事件的引用(不能用=赋值)
            h2.del += ByEnglish;//第一种
            //手工建立一个委托变量是最直接的方式。可是大多数状况下,咱们并不依靠委托对象。咱们可使用C#提供的方法组转换的方法,它容许咱们在调用以委托做为参数的方法时直接提供了与委托指望的签名想匹配的方法的名称(返回 void,参数 string),而不是建立委托对象。(因此通常直接用上面这种)
            HelloWorldDelegate de = ByChinese;
            h2.del += de;//第二种
            h2.HelloWorld("mary");
             
            Console.ReadLine();

        }

        static void ByEnglish(string name)
        {
            Console.WriteLine("hello,world"+name);
        }

        static void ByChinese(string name)
        {
            Console.WriteLine("你好,世界" + name);
        }
    }

事件默认是个多播委托,什么是多播委托呢?就是上面的h2.del委托容纳的方法有多个,ByEnglish跟ByChinese,用+=能够继续往下延伸。

委托和事件的区别在于,事件是个规约,委托是个实现(固然抽象上的委托也能够不是个具体的实现)。
规约的含义是,我定义了这么个语法,你能够经过+=和-=把委托挂载到这个东西(事件)上,当发生这个事件的时候,我会确保这些委托都被获得调用。可是具体是怎么调用的,你不用关心。

欢迎讨论~
感谢阅读~

我的公众号:

原文:http://www.cnblogs.com/joeymary/p/8486358.html

相关文章
相关标签/搜索