委托

委托是什么?

委托是一种援用类型(其实就是一个类,继承MulticastDelegate非凡的类。),示意对具备特定参数列表和返回类型的办法的援用。

每个委托提供Invoke办法, BeginInvoke和EndInvoke异步办法

为什么须要委托?

  • 委托能够将办法(即逻辑)作为参数;

    • 逻辑解耦,保持稳定。
    • 代码复用,保障我的项目标准。

如何应用委托?

如何申明、实例化和应用委托

申明委托

delegate void Del(string str);static void Notify(string name){    Console.WriteLine($"Notification received for: {name}");}

实例化委托

Del del1 = new Del(Notify);//C# 2.0Del del2 = Notify;

调用委托

del1.Invoke("小明");del2("小明");

其余应用委托

//C# 2.0应用匿名办法来申明和实例化委托Del del3 = delegate(string name){ Console.WriteLine($"Notification received for: {name}"); };//C# 3.0应用lambda表达式申明和实例化委托Del del4 = name =>  { Console.WriteLine($"Notification received for: {name}"); };

简化开发过程,.NET 蕴含一组委托类型:

  • Action<> 具备参数且不返回值。
  • Func<> 具备参数且返回由参数指定的类型的值。
  • Predicate<> 用于确定参数是否满足委托条件的状况。

理论案例

代码:

class Program{    /// <summary>    /// 申明委托    /// </summary>    /// <param name="fullName"></param>    private delegate void KillDelegate(string fullName);    static void Main(string[] args)    {        //实例化委托        var killWithKnifeDelegate = new KillDelegate(KillWithKnife);        Kill("郭靖", killWithKnifeDelegate);        var killWithSwordDelegate = new KillDelegate(KillWithSword);        Kill("黄蓉", killWithSwordDelegate);        var killWithAxeDelegate = new KillDelegate(KillWithAxe);        Kill("欧阳克", killWithAxeDelegate);        Console.ReadKey();    }    static void Kill(string fullName, KillDelegate killDelegate)    {        Console.WriteLine($"{fullName}遇到怪物");        //调用委托        killDelegate.Invoke(fullName);        Console.WriteLine($"{fullName}增长10教训");    }    static void KillWithKnife(string fullName)    {        Console.WriteLine($"{fullName}用刀杀怪物");    }    static void KillWithSword(string fullName)    {        Console.WriteLine($"{fullName}用剑杀怪物");    }    static void KillWithAxe(string fullName)    {        Console.WriteLine($"{fullName}用斧杀怪物");    }}

Lambda表达式

Lambda是什么?

Lambda就是应用委托的更不便的语法。

//C# 2.0应用匿名办法来申明和实例化委托Del del3 = delegate(string name){ Console.WriteLine($"Notification received for: {name}"); };//C# 3.0应用lambda表达式申明和实例化委托Del del4 = name =>  { Console.WriteLine($"Notification received for: {name}"); };

为什么须要Lambda?

简化开发过程,并不会影响运行性能。

如何应用Lambda?

表达式lambda根本模式:

//仅当 lambda 只有一个输出参数时,括号才是可选的;否则括号是必须的(input-parameters) => expression

应用空括号指定零个输出参数:

Action line = () => Console.WriteLine();

括号内的两个或更多输出参数应用逗号加以分隔:

Func<int, int, bool> testForEquality = (x, y) => x == y;

语句lambda

(input-parameters) => { <sequence-of-statements> }

语句 lambda 的主体能够蕴含任意数量的语句;

Action<string> greet = name =>{    string greeting = $"Hello {name}!";    Console.WriteLine(greeting);};greet("World");// Output:// Hello World!

应用匿名委托和lambda代码:

public static void Main(string[] args){    List<int> list = new List<int>();    for (int i = 1; i <= 100; i++)    {        list.Add(i);    }    //应用匿名委托    List<int> result = list.FindAll(      delegate (int no)      {          return (no % 2 == 0);      }    );    foreach (var item in result)    {        Console.WriteLine(item);    }        //应用Lambda    List<int> result = list.FindAll(i => i % 2 == 0);    foreach (var item in result)    {        Console.WriteLine(item);    }}    

事件

事件是什么?

事件是一种非凡的委托类型,次要用于音讯或告诉的传递。事件只能从事件的公布类型中调用,并且通常基于EventHandler委托,该委托具备代表事件发送者的对象和System.EventArgs派生的类,其中蕴含无关事件的数据。

何时应用委托和事件?

  • 侦听事件是可选的:如果你的代码必须调用由订阅服务器提供的代码,则应应用基于委托的设计。如果你的代码在不调用任何订阅服务器的状况下可实现其所有工作,则应应用基于事件的设计。
  • 返回值须要委托:用于事件的委托均具备有效的返回类型,事件处理程序通过批改事件参数对象的属性将信息传回到事件源。
  • 事件具备专用调用:蕴含事件的类以外的类只能增加和删除事件侦听器;只有蕴含事件的类能力调用事件。

如何应用事件?

公布事件

定义事件数据

public class CustomEventArgs : EventArgs{    public CustomEventArgs(string message)    {        Message = message;    }    public string Message { get; set; }}

申明公布类中的事件

public delegate void CustomEventHandler(object sender, CustomEventArgs args);public event CustomEventHandler RaiseCustomEvent;//应用泛型版本public event EventHandler<CustomEventArgs> RaiseCustomEvent;

订阅事件

定义一个事件处理程序办法

void HandleCustomEvent(object sender, CustomEventArgs a)  {     // Do something useful here.  } 

应用(+=) 增加订阅事件

publisher.RaiseCustomEvent += HandleCustomEvent;  

应用(-=) 勾销订阅事件

publisher.RaiseCustomEvent -= HandleCustomEvent;  

示例

using System;namespace DotNetEvents{    // 定义事件信息的类    public class CustomEventArgs : EventArgs    {        public CustomEventArgs(string message)        {            Message = message;        }        public string Message { get; set; }    }    // 公布事件的类    class Publisher    {        // 应用EventHandler <T>申明事件        public event EventHandler<CustomEventArgs> RaiseCustomEvent;        public void DoSomething()        {            RaiseCustomEvent(new CustomEventArgs("Event triggered"));        }    }    //订阅事件的类    class Subscriber    {        private readonly string _id;        public Subscriber(string id, Publisher pub)        {            _id = id;            // 增加订阅事件            pub.RaiseCustomEvent += HandleCustomEvent;        }        // 定义一个事件处理程序办法。        void HandleCustomEvent(object sender, CustomEventArgs e)        {            Console.WriteLine($"{_id} received this message: {e.Message}");        }    }    class Program    {        static void Main()        {            var pub = new Publisher();            var sub1 = new Subscriber("sub1", pub);            var sub2 = new Subscriber("sub2", pub);            // 调用引发事件的办法            pub.DoSomething();            Console.ReadKey();        }    }}

参考

  • 委托 https://docs.microsoft.com/zh...
  • Lambda表达式 https://docs.microsoft.com/zh...
  • 事件 https://docs.microsoft.com/zh...