为什么我不能使用从Sub?
在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
}
}
答案 0 :(得分:6)
事件只能从声明它们的类中调用。
从类的定义之外(即使在派生类中),您只能从event
注册和取消注册。在类的内部,编译器只允许您引发事件。这是C#的设计行为(实际上在C#4中稍有变化 - Chris Burrows describes the changes on his blog)。
您要在此处执行的操作是在基类中提供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<>
委托类型,而不是在可能的情况下创建自己的事件类型。
答案 1 :(得分:2)
因为事件只能从声明类中调用。只需在基类中创建一个方法来调用它:
protected virtual RaiseLogEvent(string s, int i)
{
log(s, i);
}
所以你可以在派生类时使用它,甚至可以覆盖它。
另外,我强烈建议您遵循事件的设计指南,并创建一个自己的EventArgs类,并使用EventHandler<T>
代理。
答案 2 :(得分:0)
是的,您可以在基类中声明事件,以便也可以从派生类中引发它们。
为事件创建受保护的调用方法。通过调用此调用方法,派生类可以调用该事件。
阅读以下标准方法在基类中声明事件,以便也可以从派生类中引发它们: