Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么可以';类中的内部事件是否在内部接口上实现事件?_C# - Fatal编程技术网

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#中的publicexplicit,无论接口的可访问性如何


这是一个“简化”规则;如果您不这样做,那么就会进入C++可访问性的泥潭,那里有公共继承、私有继承等等。我们宁愿保持简单:如果你想实现一个接口,要么让一个公共成员,要么明确地说你正在实现这个接口,C#不允许这样做,因为它坚持要么实现成员是公共的,要么它是一个明确的实现(在这种情况下,它最终将是私有的,但您仍然可以通过对接口的引用来访问它)。不过,您可以在VB.NET中这样做。

调用
MyEvent
的方式不是线程安全的。您应该创建一个防御副本,或者将事件初始化为
delegate{}
,它还有一个额外的好处,那就是你不必再担心
null
。@svick:我们有任何证据证明这个程序是多线程的吗?让一个非多线程的程序线程安全是浪费宝贵的时间。@Eric,AFAIK,我们没有。一般来说,我同意你的看法,但当修复像这样简单时,我想这样做是值得的。特别是因为
委托{}
解决方案使调用代码更简单。如果您愿意,请继续编辑它。如果使其线程安全真的那么简单,那么我欢迎改进!