.net 委托,事件(面试:猫叫了,老鼠跑了主人醒了 )其一
.net 委托,事件(面试:猫叫了,老鼠跑了主人醒了 )其二
.net 委托,事件(面试:猫叫了,老鼠跑了主人醒了 )其三
事件
事件基于委托,为委托提供了一种发布/订阅机制(观察者模式)
事件必须包含三部分:
事件的订阅者
事件的触发者/发布者
订阅者和触发者之间的数据传输通道
事件(event)的本质:事件本身其实就是一个委托链
事件与委托链的异同:
相同
- 事件的本质就是委托链,可以进行委托链的增加和移除
不同
- 事件本身时私有的,只能通过+=和-=访问
- 委托链可以随时进行增加和删除,也可以随时进行赋值(此为委托链的弊端:委托随时可以被篡改)
- 事件只能增加相同标签的动作,但是委托链可以增加不同标签的动作
问题:猫叫了一声,老鼠们跑了,主人醒了
事件三探:观察者模式
观察者:
观察者实现IObserver<bool>接口,并实现对应的函数,主要是onnext:当数据源有下一个可用时执行
/// <summary>
/// 观察者:老鼠
/// </summary>
public class Mouse2:IObserver<bool>
{
//当数据源用尽时执行
public void OnCompleted()
{
throw new NotImplementedException();
}
//当数据出现异常时执行
public void OnError(Exception error)
{
throw new NotImplementedException();
}
//当数据源下一个可用时执行
public void OnNext(bool value)
{
System.Diagnostics.Debug.WriteLine("老鼠逃跑");
}
}
/// <summary>
/// 观察者:主人
/// </summary>
public class Master2 :IObserver<bool>
{
public void OnCompleted()
{
throw new NotImplementedException();
}
public void OnError(Exception error)
{
throw new NotImplementedException();
}
public void OnNext(bool value)
{
System.Diagnostics.Debug.WriteLine("主人醒了");
}
}
发布者:
发布者实现 IObservable接口,并实现Subscribe函数,用于订阅观察者
也可以自己实现取消订阅
/// <summary>
/// 发布者:猫
/// 重要:事件应该由事件的发布者触发
/// </summary>
public class CatIssuer : IObservable<bool>
{
/// <summary>
/// 定义观察者对象
/// </summary>
private List<IObserver<bool>> affecteders;
//构造函数
public CatIssuer()
{
affecteders = new List<IObserver<bool>>();
}
/// <summary>
/// 实现接口需要实现Subscribe(订阅)方法
/// </summary>
/// <param name="observer"></param>
/// <returns></returns>
public IDisposable Subscribe(IObserver<bool> observer)
{
affecteders.Add(observer);
return null;
}
/// <summary>
/// 可自定义退订方法
/// </summary>
/// <param name="observer"></param>
public void UnSubscribe(IObserver<bool> observer)
{
}
public void Miao()
{
System.Diagnostics.Debug.WriteLine("猫叫了一声");
foreach (var observer in affecteders)
{
observer.OnNext(true);
}
}
}
通道
用于执行特定的订阅和取消订阅,并执行订阅者的方法
public class CatEvent2Controller : Controller
{
// GET: /<controller>/
public IActionResult Index()
{
var catIssuser = new CatIssuer();
var list = new List<Mouse2>() { new Mouse2(), new Mouse2(), new Mouse2()};
var master = new Master2();
///订阅老鼠
foreach (var mouse2 in list)
{
catIssuser.Subscribe(new Mouse2());
}
//订阅主人
catIssuser.Subscribe(master);
//产生数据
catIssuser.Miao();
return View();
}
}