Почему наклон я использую событие, объявленное в Основе от Sub?
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
}
}
События могут быть вызваны только из класса, который их объявляет.
За пределами определения класса (даже в производном классе) вы можете регистрироваться и отменять регистрацию только из события
. Внутри класса компилятор позволяет только инициировать событие. Это проектное поведение C # (которое на самом деле немного изменилось в C # 4 - Крис Берроуз описывает изменения в своем блоге ).
Здесь вы хотите предоставить метод 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 <>
, а не создавать свои собственные типы событий, когда это возможно.
Потому что события могут вызываться только из объявляющего класса. Просто создайте метод в базовом классе, чтобы вызвать его:
protected virtual RaiseLogEvent(string s, int i)
{
log(s, i);
}
Таким образом, вы можете использовать его для создания классов и даже переопределить его.
С другой стороны, я настоятельно рекомендую вам следовать руководящим принципам проектирования для событий, создать собственный класс EventArgs и использовать делегат EventHandler
.