2011-05-26 40 views
0

我正在编写涉及FileSystemWatcher对象的集成测试。为了使事情变得更容易,我想取消订阅活动委托中的所有内容,而不必搜索每个订阅。我已经看到相关的帖子,Is it necessary to unsubscribe from events?。这有点重复,但我特别问为什么这不适用于FileSystemWatcher对象。FileSystemWatcher事件通过System.Delegate不可触发吗?

这将是很好做类似如下:

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

http://msdn.microsoft.com/en-us/library/st6sy9xe.aspx – 2011-05-26 00:20:24

回答

1

当您在类中声明的事件,这是下面的代码的等效(几乎):

private FileSystemEventHandler _eventBackingField; 
public event FileSystemEventHandler MyFileSystemEvent 
{ 
    add 
    { 
     _eventBackingField = 
      (FileSystemEventHandler)Delegate.Combine(_eventBackingField, value); 
    } 
    remove 
    { 
     _eventBackingField = 
      (FileSystemEventHandler)Delegate.Remove(_eventBackingField, value); 
    } 
} 

注意,没有setget访问事件(如房产),你可以没有明确地写出来。

当你写在你的类MyFileSystemEvent = null,它实际上是在做_eventBackingField = null,但你的类之外,没有办法直接设置这个变量,你只有事件add & remove存取。

这可能是一个令人困惑的行为,因为在你的类中你可以通过事件名引用一个事件处理程序委托,并且不能在类之外做到这一点。

+0

感谢您的101复习课程。我必须从树上退后,这样我才能看到整个森林。 ;) – 2011-05-26 00:27:19

+0

我从你的解释中看到,创建扩展不会有帮助。能够在一个命令中转储所有订阅肯定会很好。我给这个问题一个坚定的“meh”。 – 2011-05-26 00:35:51

0

简短回答是+=-=是公共运营商,而=是宣布活动的类的私人运营商。