委託是一種引用類型(其實就是一個類,繼承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(); } } }