实现从接口

时间:2015-11-11 18:58:40

标签: c# .net events inheritance interface

在我的项目中,我需要实现一个事件,当弹出一个弹出窗口或类似的东西时会触发,以便我可以关闭任何需要隐藏的东西,无论出于何种原因。

对于上下文,我在这里有3个文件,MainShell用于触发事件,IShellMainShell实现并定义事件的接口,Reports监听事件。我可以将事件放在MainShell中并使一切变得更简单,但是如果我这样做,项目引用会变成循环。这就是我必须要做的事情。但是,我可以参考定义函数IShell使用的MainShell接口。不幸的是,似乎尝试使用派生类/接口中的事件会导致实现因某种原因变得非常复杂和挑剔。

在我的界面文件中:

public class ModuleShownEventArgs : EventArgs { }    

public delegate void ModuleShownEventHandler(object sender, ModuleShownEventArgs e);

public interface IShell {
        event ModuleShownEventHandler ModuleShown;
        ... }

在我的听力课上:

public Reports() {
    ...
    Container.Shell.ModuleShown += Shell_ModuleShown;
    ... }

private void Shell_ModuleShown(object sender, ModuleShownEventArgs e) {}

在我的射击课程中:

event ModuleShownEventHandler IShell.ModuleShown
{
    add
    {
        ((IShell)this).ModuleShown += value;
    }
    remove
    {
        ((IShell)this).ModuleShown -= value;
    }
}

public void OnModuleShown()
{
    ModuleShownEventHandler handler = ((IShell)this).ModuleShown;
    if (handler != null)
        handler(this, new ModuleShownEventArgs());
}

我设法阻止了大部分编译器的抱怨,但我遇到了一个问题:我指定handler = ModuleShown时出错,

  

事件'IShell.ModuleShown'只能出现在左侧   + =或 - =

这使我无法轻松地将我的事件与null进行比较以进行检查,并阻止我完全触发我的事件。

问题

我怎样才能让它发挥作用?为什么我不能解雇我的活动?为什么定义事件来自基类/接口时会发生如此剧烈的变化?请记住,这个项目非常庞大,我最近才开始研究它,所以我不能对它进行彻底的结构改变。

我正在使用Visual Studio 2013,而我的项目的.NET Framework版本是4.0。

2 个答案:

答案 0 :(得分:4)

问题是您正在使用显式接口实现。你应该使用隐式。

    public class Shell : IShell
    {
        public event ModuleShownEventHandler ModuleShown;

        public void OnModuleShown()
        {
            ModuleShownEventHandler handler = ModuleShown;
            if (handler != null)
            {
                handler(this, new ModuleShownEventArgs());
            }
        }
    }

https://msdn.microsoft.com/en-us/library/ms173157.aspx

理想情况下,如果您担心要从Shell实现中隐藏事件,那么您将传递实现IShell作为接口的实例。通常,当您不希望您的类公开公开特定于接口的成员时,您使用显式接口实现。

我希望这会有所帮助。

答案 1 :(得分:-2)

它应该看起来像这样。

public void OnModuleShown()
{
    if (((IShell)this).ModuleShown != null);
        (((IShell)this).ModuleShown)(this, new ModuleShownEventArgs());
}