System.Delegate无法接触的FileSystemWatcher事件

本文关键字:FileSystemWatcher 事件 接触 Delegate System | 更新日期: 2023-09-27 17:57:52

我正在编写涉及FileSystemWatcher对象的集成测试。为了让事情变得更容易,我想取消订阅活动代理的所有内容,而不必查找每个订阅。我已经看到了相关的帖子,有必要取消订阅活动吗?。这在某种程度上是重复的,但我特别想问为什么这不能用于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事件执行同样的操作。

System.Delegate无法接触的FileSystemWatcher事件

当您在类中声明事件时,它(几乎)等效于以下代码:

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访问者。

这可能是一种令人困惑的行为,因为在类内部,您可以按事件名称引用事件处理程序委托,而不能在类外部这样做。

简短的回答是+=-=是公共运算符,而=是声明事件的类的私有运算符。