如何确保实际引发来自接口的事件?

时间:2010-09-29 13:57:19

标签: c# events interface

关于接口中的事件有很多问题。这是一对夫妇:

由于接口用于强制执行合同,这对我没有意义,因为它不会强制实际引发事件。具体实现总是可以有事件,但不能在任何地方提升。请考虑以下事项:

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 个答案:

答案 0 :(得分:4)

接口契约定义必须实现事件,并且可以订阅。实际上提高它取决于具体的实施。没有办法强制引发事件。如果触发事件所需的情况永远不会发生怎么办?

答案 1 :(得分:4)

你误解了界面的概念:它明确地宣告一个对象的行为,但它没有以任何方式强制执行它。程序员仍然完全负责正确实现接口行为。这不是编译器可以做的。

当涉及的各方拒绝遵守其内容时,与其他合同相同......

托马斯

答案 2 :(得分:3)

对于方法也可以这样说:接口不强制它们做任何有用的事情,它们都可以只返回null / 0 / void。类似地,实现可以随时提高/不提升eevent。

如果要确保执行某些行为,请将它们实现为抽象基类。使公共方法公共和非虚拟,然后让它们调用虚拟保护方法并引发事件。这是template-method pattern,它可以让您更好地控制子类行为。

答案 3 :(得分:2)

永远不会提出PropertyChanged的另一种情况是财产永远不会改变的情况!你也想被警告吗?

但严重的是,接口用于强制执行支持的行为的合同 - 如果你想强制执行实际的行为(即 - 如果发生这种情况那么发生),请使用(自动化测试。

答案 4 :(得分:1)

集成测试或单元测试是我看到你能做到你想要的唯一方式。然后,您将确保在您的实现中行为符合您的期望。

答案 5 :(得分:1)

在界面中没有真正强制执行,你可以放入空方法存根(只要你返回正确类型的东西)。

确保此类行为正确的最佳方法是进行大量测试。

您可以考虑的一件事是code contracts,它允许您指定在特定时间必须为真的条件,并且这些条件实际上是强制执行的。但是,AFAIK不适用于事件。

答案 6 :(得分:0)

我的看法是,当您所有引用的是对象正在使用的接口时,这提供了一种订阅事件的方法。否则你将无法订阅该活动。您是正确的,它不能保证使用该事件。

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

如果未在INotifyPropertyChanged上定义事件,您将无法添加处理程序。