委托是一种引用类型(其实就是一个类,继承MulticastDelegate特殊的类。),表示对具备特定参数列表和返回类型的方法的引用。express
每一个委托提供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.0 Del del2 = Notify;
调用委托this
del1.Invoke("小明"); del2("小明");
其余使用委托spa
//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 包含一组委托类型:设计
代码:code
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就是使用委托的更方便的语法。对象
//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 只有一个输入参数时,括号才是可选的;不然括号是必需的 (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(); } } }