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
C# 在派生抽象类中强制实现事件_C#_Events_Interface_Delegates_Abstract - Fatal编程技术网

C# 在派生抽象类中强制实现事件

C# 在派生抽象类中强制实现事件,c#,events,interface,delegates,abstract,C#,Events,Interface,Delegates,Abstract,我正试图创建一个翻译类,这样我的程序就可以与各种目标平台对话。每个平台将由一个抽象类的单独实现来处理。为了简单起见,我把东西删减了 我有一个抽象类,有两个抽象方法: abstract class ControllerBase { public abstract bool EnableDTMFDetection(string CallID, Party Party); public abstract bool DisableDTMFDetection(string CallID,

我正试图创建一个翻译类,这样我的程序就可以与各种目标平台对话。每个平台将由一个抽象类的单独实现来处理。为了简单起见,我把东西删减了

我有一个抽象类,有两个抽象方法:

abstract class ControllerBase
{
    public abstract bool EnableDTMFDetection(string CallID, Party Party);
    public abstract bool DisableDTMFDetection(string CallID, Party Party);
}
随后,从ControllerBase派生并完全实现这些方法的一个(多个)类:

class PlatformOne : ControllerBase
{
    public override bool EnableDTMFDetection(string CallID, Party Party)
    {
        // Do Stuff
        return true;
    }

    public override bool DisableDTMFDetection(string CallID, Party Party)
    {
        // Do Stuff
        return true;
    }
}
到目前为止还不错。对于PlatformOne,我不得不定义这些方法中的每一种,规定如何向目标平台发送传出消息

是即将到来的事件吸引了我。我需要能够从派生类中引发事件。当我向controllerbase添加以下内容时:

    public delegate void MyEventHandler(object sender, EventArgs e);
    public event MyEventHandler MyEvent;
它可以很好地编译,但我无法从派生类中引发事件,而不会出现错误:“事件'ControllerBase.MyEvent'只能出现在+=或-=(从类型'ControllerBase'中使用时除外)的左侧。”


因此,a)我如何从派生类中引发事件,b)任何人都可以建议一种机制,用于从派生类(抽象函数或接口方法)中强制连接指定事件。感谢您的呼叫:)

最简单的方法是在基类中编写一个方法来提升它:

protected void OnMyEvent(EventArgs e)
{
    // Note the copy to a local variable, so that we don't risk a
    // NullReferenceException if another thread unsubscribes between the test and
    // the invocation.
    EventHandler handler = MyEvent;
    if (handler != null)
    {
        handler(this, e);
    }
}
您可能希望将其设置为虚拟方法,以便可以在派生类中重写它。。。这取决于您的用例


请注意,这并不是强制在派生类中实现任何内容,但我认为这是您真正想要的。

在抽象类中创建受保护的事件invocator

protected void InvokeMyEvent(EventArgs args)
{
    var handler = MyEvent;
    if (hander != null)
        handler(this, args);
}

标准模式是在虚拟保护方法上添加一个
,以引发事件

protected virtual OnMyEvent(EventArgs e) {
    var h = MyEvent;
    if (h != null)
        h(this, e);
}
还要记住,事件可以是抽象的或虚拟的:

public abstract event MyEventHandler MyEvent;
尽管这通常仅用于接口,但根据具体要求,哪种接口更适合您的
控制器数据库

public interface IController {
    event MyEventHandler MyEvent;
    bool EnableDTMFDetection(string CallID, Party Party);
    bool DisableDTMFDetection(string CallID, Party Party);
}

public PlatformOne : IControllerBase

    // yadda yadda...

    public event MyEventHandler MyEvent;

    // members of PlatformOne can invoke MyEvent as a normal delegate
}

似乎你需要阅读如何引发事件。另外,如果您添加与“MyEvent”相关的代码,这可能有助于回答问题。Jon-谢谢您的回答-在您的示例中,您建议我在何处以及如何创建EventHander的MyEvent实例?@Adrian:您可以在基类中将其声明为类似字段的事件,正如你在问题的底部所展示的那样。乔恩-我相信我现在有办法了,我非常感谢你。还有两个问题:当完全按照描述完成时,我需要说“var handler=MyEvent;”,而不是“EventHandler=My Event;”,其次,我完全无法理解为什么我不能在派生类中这样做——基本上是对我的初始“事件'ControllerBase.MyEvent'只能出现在+=或的左侧-=“错误。@阿德里安:我没有注意到你没有使用标准的
EventHandler
类型。您可以修改我的代码,将变量声明为type
MyEventHandler
。至于在派生类中使用事件:再次阅读谢谢,该链接完全包含了我从一开始就在寻找的内容-我敢说我需要增强我的google fu以及我的事件知识!