代码之家  ›  专栏  ›  技术社区  ›  Coding Monkey

向类方法添加事件?

  •  0
  • Coding Monkey  · 技术社区  · 16 年前

    好吧,我试过了,但我就是不明白。

    我有两个班 logger class1 .

    我有一个方法叫 logger.Write(string) 和调用的方法 class1.Execute() .

    现在在我的申请中我想 logger.Write(class1.ToString()) 运行时 类1.执行() 被称为。

    我想你需要增加代表和活动,但我就是没法理解这一点,已经花了几个小时。

    一件事是,记录器和类位于不同的命名空间中,如果可能的话,我不想为它们中的任何一个更新类代码。

    3 回复  |  直到 16 年前
        1
  •  6
  •   Jon Skeet    16 年前

    当然,如果不更改任何一个类中的代码,就不能这样做(假设您也不想更改调用的所有地方 class1.Execute )-至少没有一些深层的代码编织/仪器魔术。但是,您可以很容易地将事件添加到 Class1 :

    public class Class1
    {
        // TODO: Think of a better name :)
        public event EventHandler ExecuteCalled = delegate {};
    
        public void Execute()
        {
            ExecuteCalled(this, EventArgs.Empty);
            // Do your normal stuff
        }
    }
    

    这个 delegate{} 位只是为了确保始终至少注册了一个no-op事件处理程序-这意味着您不需要检查是否为空。

    然后你会写下:

    Class1 class1 = new Class1();
    Logger logger = new Logger();
    class1.ExecuteCalled += (sender, args) => logger.Write(sender.ToString());
    

    (假设您使用的是C 3,所以您可以使用lambda表达式-如果不是这样,请告诉我。)

    如果 第一类 实现一个接口(比如 IFoo ,您可能希望编写一个包含另一个实现的接口的实现,并在每次调用之前记录:

    public sealed class LoggingFoo : IFoo
    {
        private readonly IFoo original;
        private readonly IFoo logger;
    
        public LoggingFoo(IFoo original, Logger logger)
        {
            // TODO: Check arguments for nullity
            this.original = original;
            this.logger = logger;
        }
    
        // Implement IFoo
        public void Execute()
        {
            logger.Write("Calling Execute on {0}", original);
            original.Execute();
        }
    }
    

    然后,只要在当前只使用实现的任何地方使用一个“真实”实现的包装器。

        2
  •  2
  •   jasonh    16 年前

    你能为记录器传递一个对象参数,然后就调用它的toString吗?将调用适当的ToString方法。如果不想更改logger或class1中的任何内容,那么可以编写一个扩展方法并调用它,而不是调用class1.execute。此方法将调用Logger,然后调用Class1.Execute。

    public static ExecuteAndLog(this class1 obj)
    {
        logger.Write(obj.ToString());
        obj.Execute();
    }
    

    然后您只需调用obj.executeandlog();

        3
  •  0
  •   Jon Limjap    16 年前

    您需要声明 EventHandler 对于 Class1

    public event EventHandler OnExecute;
    

    在执行方法中:

    public void Execute()
    {
       //...
       if (OnExecute != null)
           OnExecute(this, null);
    }
    

    当你在其他地方使用Class1时,这就是你将事件放在那里的地方;

    private Class1 class1 = new Class1();
    class1.OnExecute += SomeMethodName;
    
    public void SomeMethodName(sender obj, EventArgs e)
    {
        logger.Write(class1.ToString());
    }
    

    我们可以定制 EventHandlers 因为如果您需要更多的信息,但是对于无参数的准系统事件,这应该是有效的。