在子类中使用event和delegate

klu*_*dby 6 c# events delegates

为什么我不能使用从Base中声明的事件?

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 wont compile
    }
}
Run Code Online (Sandbox Code Playgroud)

LBu*_*kin 7

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

从类的定义之外(即使在派生类中),您只能注册和取消注册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 );
      }
  }
} 
Run Code Online (Sandbox Code Playgroud)

另外,您应该考虑使用EventHandler<>委托类型,而不是在可能的情况下创建自己的事件类型.