共计 4316 个字符,预计需要花费 11 分钟才能阅读完成。
委托
委托是什么?
委托是一种援用类型(其实就是一个类,继承 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.0 | |
Del 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…
正文完