繁体   English   中英

在子类中使用事件和委托

[英]Use event and delegate in subclass

为什么我不能使用SubBase声明的事件?

class Program
{
    static void Main(string[] args)
    {
        Sub sub = new Sub();
        sub.log += new Base.logEvent(sub_log);
        sub.go();
    }

    static void sub_log(string message, int level)
    {
        Console.Out.WriteLine(message + " " + level);
    }
}

public abstract class Base
{
    public delegate void logEvent(String message, int level);

    public event logEvent log;
}

public class Sub : Base
{

    public void go()
    {
        log("Test", 1); // <-- this won't compile
    }
}

事件只能从声明它们的类中调用。

在类的定义之外(即使在派生类中),您只能从event注册和注销。 在类内部,编译器只允许您引发事件。 这是 C# 的设计行为(实际上在 C#4 中略有变化 -Chris Burrows 在他的博客上描述了这些变化)。

您在这里要做的是在基类中提供一个RaiseLogEvent()方法,这将允许派生类调用此事件。

public abstract class Base
{ 
  public delegate void logEvent(String message, int level); 

  public event logEvent log; 

  protected void RaiseLogEvent( string msg, int level )
  {
      // note the idomatic use of the copy/test/invoke pattern...
      logEvent evt = log;
      if( evt != null )
      {
          evt( msg, level );
      }
  }
} 

EventHandler<> ,您应该考虑使用EventHandler<>委托类型,而不是尽可能创建自己的事件类型。

因为事件只能从声明类中调用。 只需在基类中创建一个方法来调用它:

protected virtual RaiseLogEvent(string s, int i)
{
  log(s, i);
}

所以你可以在派生类中使用它,甚至可以覆盖它。

另一方面,我强烈建议您遵循事件的设计指南,创建自己的 EventArgs 类,并使用EventHandler<T>委托。

是的,您可以在基类中声明事件,以便它们也可以从派生类中引发。

为事件创建一个受保护的调用方法。 通过调用这个调用方法,派生类可以调用事件。

在此处阅读执行此操作的标准方法:
如何在派生类中引发基类事件

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM