C# 为什么可以';类中的内部事件是否在内部接口上实现事件?
我有一个定义一些事件的内部接口和一个实现该接口的示例类:C# 为什么可以';类中的内部事件是否在内部接口上实现事件?,c#,C#,我有一个定义一些事件的内部接口和一个实现该接口的示例类: internal interface IMyEvents { event EventHandler MyEvent; } public class MyClass : IMyEvents { internal event EventHandler MyEvent; public void DoSomething() { if (MyEvent != null) MyEvent(this,
internal interface IMyEvents
{
event EventHandler MyEvent;
}
public class MyClass : IMyEvents
{
internal event EventHandler MyEvent;
public void DoSomething()
{
if (MyEvent != null) MyEvent(this, new EventArgs());
}
}
当我尝试编译时,出现以下错误:
error CS0737: 'MyClass' does not implement interface member '.IMyEvents.MyEvent'. 'MyClass.MyEvent' cannot implement an interface member because it is not public.
这是怎么回事?它是一个内部接口,所以我不明白为什么事件必须公开。您需要显式实现
IMyEvents
public class MyClass : IMyEvents
{
// ...
event EventHandler IMyEvents.MyEvent
{
add { MyEvent += value; }
remove { MyEvent -= value; }
}
}
实现接口的成员必须是C#中的public或explicit,无论接口的可访问性如何
这是一个“简化”规则;如果您不这样做,那么就会进入C++可访问性的泥潭,那里有公共继承、私有继承等等。我们宁愿保持简单:如果你想实现一个接口,要么让一个公共成员,要么明确地说你正在实现这个接口,C#不允许这样做,因为它坚持要么实现成员是公共的,要么它是一个明确的实现(在这种情况下,它最终将是私有的,但您仍然可以通过对接口的引用来访问它)。不过,您可以在VB.NET中这样做。调用
MyEvent
的方式不是线程安全的。您应该创建一个防御副本,或者将事件初始化为delegate{}
,它还有一个额外的好处,那就是你不必再担心null
。@svick:我们有任何证据证明这个程序是多线程的吗?让一个非多线程的程序线程安全是浪费宝贵的时间。@Eric,AFAIK,我们没有。一般来说,我同意你的看法,但当修复像这样简单时,我想这样做是值得的。特别是因为委托{}
解决方案使调用代码更简单。如果您愿意,请继续编辑它。如果使其线程安全真的那么简单,那么我欢迎改进!