簡體   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