gab*_*abe 34 c# events delegates event-handling
我确信我只是不了解C#中事件和/或委托的基本内容,但为什么我不能在此代码示例中进行布尔测试:
public class UseSomeEventBase {
public delegate void SomeEventHandler(object sender, EventArgs e);
public event SomeEventHandler SomeEvent;
protected void OnSomeEvent(EventArgs e) {
// CANONICAL WAY TO TEST EVENT. OF COURSE, THIS WORKS.
if (SomeEvent != null) SomeEvent(this, e);
}
}
public class UseSomeEvent : UseSomeEventBase {
public bool IsSomeEventHandlerNull() {
// "LEFT HAND SIDE" COMPILER ERROR
return SomeEvent == null;
}
}
class Program {
static void Main(string[] args) {
var useSomeEvent = new UseSomeEvent();
useSomeEvent.SomeEvent +=new UseSomeEventBase.SomeEventHandler(FuncToHandle);
// "LEFT HAND SIDE" COMPILER ERROR
if (useSomeEvent.SomeEvent == null) {
}
var useSomeEventBase = new UseSomeEventBase();
useSomeEventBase.SomeEvent += new UseSomeEventBase.SomeEventHandler(FuncToHandle);
// "LEFT HAND SIDE" COMPILER ERROR
if (useSomeEventBase.SomeEvent == null) {
}
}
static void FuncToHandle(object sender, EventArgs e) { }
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 58
事件实际上只是一个"添加"操作和一个"删除"操作.您无法获取值,您无法设置该值,您无法调用它 - 您只需为事件(add)订阅处理程序或取消订阅一个(remove).这很好 - 它的封装,简单明了.由发布者适当地实施添加/删除,但除非发布者选择提供详细信息,否则订阅者无法修改或访问特定于实现的部分.
C#中的字段式事件(您没有指定添加/删除位)隐藏了这一点 - 它们创建委托类型和事件的变量.事件的添加/删除实现只是使用该变量来跟踪订阅者.
在类中你引用变量(所以你可以获得当前订阅的委托,执行它们等),在类之外你引用事件本身(所以只有添加/删除功能).
类似字段事件的替代方法是您自己显式实现添加/删除,例如
private EventHandler clickHandler; // Normal private field
public event EventHandler Click
{
add
{
Console.WriteLine("New subscriber");
clickHandler += value;
}
remove
{
Console.WriteLine("Lost a subscriber");
clickHandler -= value;
}
}
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅我关于事件的文章
当然,事件发布者也可以提供更多信息 - 您可以编写一个属性,例如ClickHandlers返回当前的多播委托,或者HasClickHandlers返回是否存在.但这并不是核心事件模型的一部分.
Sun*_*nil 16
您可以在此处轻松使用非常简单的方法来重复订阅事件.
可以使用以下两种方法中的任何一种:
标记方法:_getWarehouseForVendorCompletedSubscribed是一个初始化为false的私有变量.
if (!_getWarehouseForVendorCompletedSubscribed)
{
_serviceClient.GetWarehouseForVendorCompleted += new EventHandler<GetWarehouseForVendorCompletedEventArgs>(_serviceClient_GetWarehouseForVendorCompleted);
_getWarehouseForVendorCompletedSubscribed = true;
}
Run Code Online (Sandbox Code Playgroud)取消订阅方法:每次订阅时都包含取消订阅.
_serviceClient.GetWarehouseForVendorCompleted -= new
EventHandler<GetWarehouseForVendorCompletedEventArgs>
(_serviceClient_GetWarehouseForVendorCompleted);
_serviceClient.GetWarehouseForVendorCompleted += new
EventHandler<GetWarehouseForVendorCompletedEventArgs>
(_serviceClient_GetWarehouseForVendorCompleted);
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
29278 次 |
| 最近记录: |