最近学习委托和事件的时候,有了一点自己的理解,顾写下来当做积累。
举个例子,当我们做电梯的时候,我们会按下自己要去的楼层,电梯会
自动告诉电梯里的所有人当前的楼层。这就类似于委托的广播。人进入电梯
就默认订阅了电梯的楼层播报事件。先看代码:
首先有一个人类:
public class Person
{
/// <summary>
/// 人进入电梯
/// </summary>
/// <param name="elevator">进入的电梯对象</param>
public void InElevator(Elevator elevator)
{
elevator.reportLevel += GetFloorMessage; //注册委托方法
}
/// <summary>
/// 得到电梯播报的楼层信息
/// </summary>
/// <param name="message">楼层信息</param>
public void GetFloorMessage(string message)
{
Console.WriteLine(message);
}
}
然后是电梯类和一个委托:
/// <summary>
/// 播报楼层的委托
/// </summary>
/// <param name="message">楼层信息</param>
public delegate void ReportFloor(string message);
public class Elevator
{
public ReportFloor reportLevel; //电梯委托对象
/// <summary>
/// 电梯报楼层
/// </summary>
/// <param name="message">楼层信息</param>
public void ElevatorReport(string message)
{
reportLevel(message);
}
}
下面是Main方法:
/// <summary>
/// 电梯对象
/// </summary>
private static Elevator elevator;
static void Main()
{
elevator = new Elevator();
Person p1 = new Person();
p1.InElevator(elevator); //进入电梯
Person p2 = new Person();
p2.InElevator(elevator);//进入电梯
elevator.ElevatorReport("三层到了");
}
例子很简单,大概意思就是人进入电梯,接受电梯的播报事件,电梯播放当前楼层。
正常情况下是合理的,但是有一个问题,委托本身不属于对象,委托应该可以说是和类一个级别的,
这就意味着,委托谁都可以触发而不单单是电梯来触发了。比如 在人类中加一个触发电梯播报的方法:
///人为触发电梯的播报
/// </summary>
/// <param name="elevator">要触发的电梯</param>
public void ControlElevator(Elevator elevator)
{
elevator.reportLevel("五层到了");
}
当一个person对象调用这个方法的时候,相当于让电梯播没有到的楼层,这肯定是不合理的。怎么才能让播报只有电梯对象本身才能够触发呢?这时候就可以用事件。看代码:
将电梯里的委托改为事件,
public class Elevator
{
public event ReportFloor reportLevel; //电梯委托对象
/// <summary>
/// 电梯报楼层
/// </summary>
/// <param name="message">楼层信息</param>
public void ElevatorReport(string message)
{
reportLevel(message);
}
}
这时候,就不能通过 elevator.reportLevel("五层到了");来触发事件了,因为事件在外部只能被注册,而执行只能在事件的所有者中执行。这样就有了一个规范,同时也实现了对象的封闭原则。对于没有特定约束的情况下,我个人觉得好像没有什么太大的区别了。我记得跨线程访问方法的时候想用委托就比较方便。
委托的返回值
一般情况下委托的返回类型都是void,因为委托在多播的情况下,如果有返回值,只会得到最后一个执行的方法的返回值,因为其他方法的返回值被覆盖掉了(代码实验的时候发现返回值等于最后一个执行的返回值,所有这样认为)。
这里只是一些个人的理解,对或不对,欢迎看到的朋友拍砖,指正。
转载于:https://blog.51cto.com/qiang1228/691458