使用事件和子类委托 [英] Use event and delegate in subclass

查看:115
本文介绍了使用事件和子类委托的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么不能我使用基地申报的情况下,从子?



 类节目
{
静态无效的主要(字串[] args)
{
子子=新的子();
sub.log + =新Base.logEvent(sub_log);
sub.go();
}

静态无效sub_log(字符串消息,INT级)
{
Console.Out.WriteLine(信息++级);
}
}

公共抽象类基地
{
公众委托无效LOGEVENT(字符串消息,INT级);

公共事件日志LOGEVENT;
}

公共类分:基本
{

公共无效围棋()
{
日志(测试 ,1); //< - 这不会编译
}
}


解决方案

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



从一个类的定义之外(甚至在派生类),你只能注册并从事件注销。在类中,编译器只允许您引发事件。这是C#中通过设计行为(实际上在C#4稍有变化 - 的克里斯·伯罗斯描述了在他的博客的变化)。



你想在这里做的是提供了一个 RaiseLogEvent()在基类中,这将使派生类中调用该事件的方法。

 公共抽象类基地
{
公众委托无效LOGEVENT(字符串消息,INT级);

公共事件日志LOGEVENT;

保护无效RaiseLogEvent(string信息,INT级)
{
//注意idomatic使用拷贝/测试/调用模式...
LOGEVENT EVT =记录;
如果(EVT!= NULL)
{
EVT(味精,水平);
}
}
}



顺便说一句,你应该考虑使用事件处理程序和LT;方式> 委托类型,而不是创建自己的事件类型时可能


Why cant i use the event declared in Base from 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
    }
}

解决方案

Events may only be invoked from the class that declares them.

From outside of the definition of a class (even in a derived class) you can only register and unregister from an event. Inside of the class, the compiler only allows you to raise the event. This is a by-design behavior of C# (which actually changes slightly in C#4 - Chris Burrows describes the changes on his blog).

What you want to do here is provide a RaiseLogEvent() method in the base class, which would allow the derived class to invoke this event.

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 );
      }
  }
} 

As an aside, you should consider using the EventHandler<> delegate type, rather than creating your own event types when possible.

这篇关于使用事件和子类委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆