委托和事件
发布者.委托 += 订阅者.事件处理程序
发布者
{
在其他成员方法种
委托?。INvoke(this,事件参数)
有可能通过一个public方法封装委托让外界把我事件发布的时机(虽然这很不被推荐)。还有清空订阅的方法,保证始终只有一个订阅者的的方法等等。
}
.NET标准的事件模型要求,事件委托是public,外界能拿到委托引用来注册事件处理程序,即允许observableObject.PropertyChanged += xxx,但不支持observableObject.PropertyChanged = xxx,这样会清空其他订阅者的订阅。订阅者只允许订阅,不允许牵涉别的订阅者的订阅,清空订阅应当再封装个方法。
如果想暴露,object,eventargs. huo eventargs.
也不支持发布事件。所以这些方法都是protected,如果是public的,相当于把event的作用抵消,除了this。
这些方法的核心目的都是为了调用event PropertyChanged发布某某属性的值发生了改变这一事件。
event有哪些约束,约束的作用是什么?
发布者必须暴露委托供外界订阅,所以外界可以访问委托,可以+=订阅,可以=,可以Invoke,加上event后,外界只能+=,不能=,因为某个订阅者理应只能决定自身进行订阅或者取消订阅,不能影响别人的订阅情况。也不能Invoke,发布者最了解发布的时机,外界没有那么了解,如果错误的发布,没发生事件却谎报军情说发生了,又或者发生了但是没发布,这可能都导致极大的副作用!
同时内部调用Invoke(),保证了sender是this,外界的话,可能乱传递发布者引用,导致不是发布者本身。
如何破解event的约束?
发布者可以提供一个public的方法封装事件调用,
public void Publish(object sender,EventArgs e)
{
PropertyChanged?.Invoke(sender,e);
}
或者一定程度上暴露发布事件的时机和事件参数,但是不暴露事件发布者。
public void Publish(EventArgs e)
{
PropertyChanged?.Invoke(this,e);
}
又或者只暴露事件发布的时机,但是不暴露事件的发布者和事件参数。
public void Publish()
{
PropertyChanged?.Invoke(this,new EventArgs());
}
其实WPF种的命令就是提供了这种封装。 CanExecuteChanged(this,EventArgs.Empty),之所以暴露,是因为命令本身也不晓得何时发布事件。
清空委托中的所有方法
通过委托的方法 GetInvocationList 得到此委托中所挂载的所有的方法一次行删除
myDe += p.SayB;
Console.WriteLine(myDe);
Delegate[] ar = myDe.GetInvocationList();
myDe("Aonaufly");
for (int i = 0; i < ar.Length; i++)
{
myDe -= ar[i] as Delistener;
}