关于接口中的事件有很多问题。这是一对夫妇:
由于接口用于强制执行合同,这对我没有意义,因为它不会强制实际引发事件。具体实现总是可以有事件,但不能在任何地方提升。请考虑以下事项:
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事件,也不会发生任何事情。什么是强制实际引发事件的方法,如果没有,为什么首先在接口中有事件?
答案 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上定义事件,您将无法添加处理程序。