C# 语言设计:事件的显式接口实现
关于 C# 语言设计的小问题:))
如果我有一个这样的接口:
interface IFoo {
int Value { get; set; }
}
可以使用 C# 3.0 自动实现的属性显式实现这样的接口:
sealed class Foo : IFoo {
int IFoo.Value { get; set; }
}
但是如果我在接口中有一个事件:
interface IFoo {
event EventHandler Event;
}
并尝试使用 field 显式实现它类似事件:
sealed class Foo : IFoo {
event EventHandler IFoo.Event;
}
我将收到以下编译器错误:
错误CS0071:事件的显式接口实现必须使用事件访问器语法
我认为类似字段的事件是自动的某种二元论实施的属性。
所以我的问题是:进行此类限制的设计原因是什么?
Small question about C# language design :))
If I had an interface like this:
interface IFoo {
int Value { get; set; }
}
It's possible to explicitly implement such interface using C# 3.0 auto-implemented properties:
sealed class Foo : IFoo {
int IFoo.Value { get; set; }
}
But if I had an event in the interface:
interface IFoo {
event EventHandler Event;
}
And trying to explicitly implement it using field-like event:
sealed class Foo : IFoo {
event EventHandler IFoo.Event;
}
I will get the following compiler error:
error CS0071: An explicit interface implementation of an event must use event accessor syntax
I think that field-like events is the some kind of dualism for auto-implemented properties.
So my question is: what is the design reason for such restriction done?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有趣的问题。我翻阅了语言注释档案,发现这个决定是在 1999 年 10 月 13 日做出的,但注释没有给出该决定的理由。
在我的脑海中,我看不出有任何理论或实践原因解释为什么我们不能有类似领域的显式实现事件。我也不认为我们有任何特别需要这样做的理由。这可能仍是未知之谜之一。
Interesting question. I did some poking around the language notes archive and I discovered that this decision was made on the 13th of October, 1999, but the notes do not give a justification for the decision.
Off the top of my head I don't see any theoretical or practical reason why we could not have field-like explicitly implemented events. Nor do I see any reason why we particularly need to. This may have to remain one of the mysteries of the unknown.
我想这可能与您无法从类的其他成员调用显式接口实现这一事实有关:
请注意,您可以通过首先向上转换到接口来调用该方法:
((I)this) .DoIt();
。有点难看,但它有效。如果事件可以按照 ControlFlow(OP)的建议显式实现,那么您实际上会如何引发它们?考虑一下:
在这里,您甚至无法通过首先向上转换到接口来引发事件,因为事件只能从实现类内部引发。因此,要求显式实现事件的访问器语法似乎是完全有意义的。
I guess it might have to do with the fact that you can't call an explicit interface implementation from other members of the class:
Note that you can call the method by upcasting to the interface first:
((I)this).DoIt();
. A bit ugly but it works.If events could be explicitly implemented as ControlFlow (the OP) suggested, then how would you actually raise them? Consider:
Here you cannot even raise the event by upcasting to the interface first, because events can only be raised from within the implementing class. It therefore seems to make perfect sense to require accessor syntax for explicitly implemented events.
当显式实现在接口中声明的事件时,您必须手动提供通常由编译器提供的添加和删除事件访问器。访问器代码可以将接口事件连接到类中的另一个事件或其自己的委托类型。
例如,这将触发错误 CS0071:
正确的方法是:
请参阅 编译器错误 CS0071
When explicitly implementing an event that was declared in an interface, you must use manually provide the add and remove event accessors that are typically provided by the compiler. The accessor code can connect the interface event to another event in your class or to its own delegate type.
For example, this will trigger error CS0071:
The correct way would be:
see Compiler Error CS0071
这实际上并不是我自己的原创想法。
不过,我想我可以回应一下:
在《程序员 C# 简介》第二版的第 23 章中,Eric Gunnerson 写道:
...
他在接下来的几页中继续评论包括 add() 和 remove() 方法来实现此行为;能够直接写入这些方法以及为不需要的委托引用分配存储空间的结果。
我想补充更多,但我非常尊重作者,未经他的许可我不会这样做。我建议找到这本书的副本,并会推荐埃里克·冈纳森(Eric Gunnerson)的任何一般内容(博客等......)
无论如何,我希望这与该主题相关,如果是这样,希望它能揭示这个“未知之谜” “? (我正在阅读这一章并搜索 Stack Overflow,以深入了解从自定义对象创建自定义集合时的事件处理程序逻辑注意事项) - 我只提到这一点,因为我在这个特定主题上没有特定的权威。我自己只是一个寻求“启蒙”的学生:-)
This would not actually be an original thought by myself.
However, I thought I might respond to this:
In Chapter 23 of A Programmer's Introduction to C#, Second Edition, Eric Gunnerson wrote:
...
He goes on over the next few pages to comment on including the add() and remove() methods to implement this behavior; being able to write to those methods directly and the consequence of storage allocation for unneeded delegate references.
I would add more, but I respect the author too much to do so without his permission. I recommend finding a copy of this book and would recommend anything by Eric Gunnerson in general (blog, etc...)
Anyway, I hope this is relevant to the topic and if so, hope it shines light on this "mystery of the unknown"? (I was reading this very chapter and searching Stack Overflow for insight into event handler logic considerations when creating custom collections from custom objects) - I only mention this because I claim no specific authority on this particular subject. I am merely a student in search of "enlightenment" myself :-)