События FileSystemWatcher, недоступные для System.Delegate? - PullRequest
0 голосов
/ 26 мая 2011

Я пишу интеграционные тесты, которые включают объекты 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.

Ответы [ 2 ]

1 голос
/ 26 мая 2011

Когда вы объявляете событие в вашем классе, оно эквивалентно (почти) следующему коду:

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. Accessors.

Это может привести к путанице, поскольку внутри вашего класса вы можете ссылаться на делегат обработчика событий по имени события и не можете делать это вне класса.

0 голосов
/ 26 мая 2011

Краткий ответ: += и -= - публичные операторы, а = - приватный оператор для класса, который объявляет событие.

...