Как убедиться, что событие из интерфейса действительно вызвано? - PullRequest
1 голос
/ 29 сентября 2010

Есть много вопросов о событиях в интерфейсах. Вот пара:

Поскольку интерфейсы используются для принудительного исполнения контракта для реализации, для меня это не имеет смысла, поскольку не обеспечивает фактического возбуждения события. Конкретная реализация всегда может иметь событие, но нигде не вызывать его. Учтите следующее:

public interface INotifyPropertyChanged
{
    event PropertyChangedEventHandler PropertyChanged;
}

public class SomeClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string SomeProperty
    {
        get { return this.someField; }
        set { this.someField = value; }
    }

    private string someField;
}

Сказанное выше скомпилирует и сработает, но даже если я подпишусь на событие PropertyChanged, ничего не произойдет. Каким образом можно добиться того, чтобы событие действительно вызывалось, и если нет, то зачем вообще иметь события в интерфейсах?

Ответы [ 7 ]

4 голосов
/ 29 сентября 2010

Вы неправильно поняли концепцию интерфейса: он явно объявляет поведение объекта, но он не обеспечивает его каким-либо образом.Программист по-прежнему полностью отвечает за правильную реализацию поведения интерфейса.Это ничего не может сделать компилятор.

Это то же самое, что и с другими контрактами, когда вовлеченные стороны просто отказываются придерживаться его содержания ...

Thomas

4 голосов
/ 29 сентября 2010

Контракт интерфейса определяет, что событие должно быть реализовано и на него можно подписаться. На самом деле его поднятие оставлено до конкретной реализации. Нет никакого способа заставить это событие возникнуть. Что если обстоятельства, необходимые для запуска события, никогда не произойдут?

3 голосов
/ 29 сентября 2010

То же самое можно сказать и о методах: интерфейс не требует, чтобы они делали что-либо полезное, они могут просто вернуть null / 0 / void. Точно так же реализация может свободно поднимать / не поднимать событие, когда захочет.

Если вы хотите обеспечить выполнение определенных поведений, то реализуйте их как абстрактный базовый класс. Сделайте открытые методы открытыми и не виртуальными, а затем заставьте их вызывать виртуальные защищенные методы и вызывать события. Это шаблон шаблона , и он позволяет вам лучше контролировать поведение подкласса.

2 голосов
/ 29 сентября 2010

Еще одна ситуация, в которой PropertyChanged никогда не возникнет, - это то обстоятельство, что свойство никогда не изменяется! Вы тоже хотите, чтобы вас об этом предупреждали?

А если серьезно, интерфейсы предназначены для обеспечения исполнения контракта поддерживаемого поведения - если вы хотите применить фактическое поведение (т. Е. - ЕСЛИ это происходит ТОГДА, что происходит), используйте (автоматизировано) тестирование.

1 голос
/ 29 сентября 2010

В интерфейсе нет ничего обязательного, вы можете просто вставить пустые заглушки для методов (если вы возвращаете что-то правильного типа).

Лучший способ убедиться, что такие вещи ведут себя правильно, - это пройти множество тестов.

Одна вещь, которую вы могли бы рассмотреть - это кодовые контракты , которые позволяют вам указывать условия, которые должны выполняться в определенные моменты времени, и они фактически выполняются. Однако, AFAIK, это не работает с событиями.

1 голос
/ 29 сентября 2010

Интеграционные тесты или юнит-тесты - это единственный способ, которым я вижу, что вы можете делать то, что вы хотите.Затем вы убедитесь, что в своей реализации поведение соответствует ожидаемому.

0 голосов
/ 29 сентября 2010

Я предполагаю, что это обеспечивает возможность подписки на событие, когда все, на что вы ссылаетесь - это интерфейс, который использует объект. В противном случае вы не сможете подписаться на событие вообще. Вы правы, что это не гарантирует, что событие используется.

INotifyPropertyChanged x = new SomeClass();
x.PropertyChanged += MyHandler;  //you get the idea

Если событие не было определено в INotifyPropertyChanged, вы не сможете добавить свой обработчик.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...