我正在编写涉及FileSystemWatcher对象的集成测试。为了简化操作,我想取消订阅活动代表的所有内容,而无需追捕每个订阅。我已经看过相关的帖子,Is it necessary to unsubscribe from events?。这有点重复,但我特别问为什么这不适用于FileSystemWatcher对象。
做以下事情会很好:
private void MethodName()
{
var watcher = new FileSystemWatcher(@"C:\Temp");
watcher.Changed += new FileSystemEventHandler(watcher_Changed);
watcher.Changed = null; // A simple solution that smells of C++.
// A very C#-ish solution:
foreach (FileSystemEventHandler eventDelegate in
watcher.Changed.GetInvocationList())
watcher.Changed -= eventDelegate;
}
无论引用Changed事件如何,编译器都会报告: 事件'System.IO.FileSystemWatcher.Changed'只能出现在+ =或 - = 的左侧
当处理同一个类中的事件时,上面的代码工作得很好:
public event FileSystemEventHandler MyFileSystemEvent;
private void MethodName()
{
MyFileSystemEvent += new FileSystemEventHandler(watcher_Changed);
MyFileSystemEvent = null; // This works.
// This works, too.
foreach (FileSystemEventHandler eventDelegate in
MyFileSystemEvent.GetInvocationList())
watcher.Changed -= eventDelegate;
}
那么,我错过了什么?看来我应该能够对FileSystemWatcher事件做同样的事情。
答案 0 :(得分:1)
当您在类中声明事件时,它是以下代码的等效(几乎):
private FileSystemEventHandler _eventBackingField;
public event FileSystemEventHandler MyFileSystemEvent
{
add
{
_eventBackingField =
(FileSystemEventHandler)Delegate.Combine(_eventBackingField, value);
}
remove
{
_eventBackingField =
(FileSystemEventHandler)Delegate.Remove(_eventBackingField, value);
}
}
请注意,事件没有set
或get
访问者(如属性),您无法明确地编写它们。
当你在课堂上写MyFileSystemEvent = null
时,它实际上正在_eventBackingField = null
,但在课堂之外无法直接设置此变量,只有事件add
& remove
访问者。
这可能是一种令人困惑的行为,因为在您的类中,您可以按事件名称引用事件处理程序委托,并且不能在该类之外执行该操作。
答案 1 :(得分:0)
简短回答是+=
,-=
是公共运营商,而=
是宣布该活动的类的私有运营商。