创建或删除时触发事件

时间:2014-02-26 09:09:04

标签: c# delegates event-handling

我希望在创建(或删除)类实例时触发事件,但我的类本身。 这似乎是不可能的(因为没有其他类实例可以同时创建对象并在创建的类的事件上添加处理程序)。还有其他方法吗?

public class MyClass {
public delegate void delegate_MyClassCreated( MyClass me);
public delegate_MyClassCreated event_MyClassCreated;

public delegate void delegate_MyClassDeleted( MyClass me);
public delegate_MyClassDeleted event_MyClassDeleted;

public MyClass() {

    //... some initialisations here...

    try {
        event_MyClassCreated( this);
        }
    catch {}
    }

~ MyClass() {
    try {
        event_MyClassDeleted( this);
        }
    catch {}
    }
}

//...
// in other class
((MyClass)new MyClass()).event_MyClassCreated += callback_MyClassCreated;
// ...

void callback_MyClassCreated( MyClass me) {
    // action on me
    }

2 个答案:

答案 0 :(得分:0)

为什么不使用静态事件?这样的事情:

  public class MyClass {
    ...
    // static event doesn't need any instance and so 
    // could be called within constructor
    public static event EventHandler MyClassCreated;

    public MyClass() {
      ...

      if (!Object.ReferenceEquals(null, MyClassCreated))
        MyClassCreated(this, EventArgs.Empty);
    } 
  }

...

  // Assigning callback for the event (no MyClass instance required)
  MyClass.MyClassCreated += callback_MyClassCreated;

答案 1 :(得分:0)

使用IoC容器,例如Autofac: - )

我不确定Unity,但至少Autofac有所谓的激活事件,您可以在这里以一般方式或特定类型处理实例的创建。 看看这个blog post

如果您不想使用,例如Autofac,你可能会留下一个DIY实现。 - 这可能是为您的类实现工厂,作为实例化过程的一部分,它会触发事件。

使用静态事件的Quick'n'Dirty DIY示例:

using System;

namespace ConsoleApplication2
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var myCreatingEventHandler = new EventHandler((sender, eventArgs) => Console.WriteLine("Creating"));
            var myCreatingEventHandler2 = new EventHandler((sender, eventArgs) => Console.WriteLine("Creating2"));
            var myDisposingEventHandler = new EventHandler((sender, eventArgs) => Console.WriteLine("Disposing"));
            var myDisposingEventHandler2 = new EventHandler((sender, eventArgs) => Console.WriteLine("Disposing2"));

            MyClass.Creating += myCreatingEventHandler;
            MyClass.Disposing += myDisposingEventHandler;
            using (var test = new MyClass())
            {
                // Prints "Creating" and "Disposing".
            }

            Console.WriteLine();

            MyClass.Creating += myCreatingEventHandler2;
            MyClass.Disposing += myDisposingEventHandler2;
            using (var test = new MyClass())
            {
                // Prints "Creating", "Creating2", "Disposing" and "Disposing2".
            }

            Console.WriteLine();

            MyClass.Creating -= myCreatingEventHandler;
            MyClass.Disposing -= myDisposingEventHandler;
            using (var test = new MyClass()) {
                // Prints "Creating2" and "Disposing2".
            }

            Console.WriteLine();

            MyClass.Creating -= myCreatingEventHandler2;
            MyClass.Disposing -= myDisposingEventHandler2;
            using (var test = new MyClass())
            {
                // Prints nothing (removed subscriptions to avoid "memory leak".
            }

            // You may choose call such a method to ensure that ALL handlers are removed from the invocation list.
            MyClass.RemoveSubscriptions();

            Console.ReadKey();
        }
    }

    internal class MyClass : IDisposable
    {
        public static event EventHandler Creating;

        private static void OnCreating()
        {
            EventHandler handler = Creating;
            if (handler != null) handler(null, EventArgs.Empty);
        }

        public static event EventHandler Disposing;

        private static void OnDisposing()
        {
            EventHandler handler = Disposing;
            if (handler != null) handler(null, EventArgs.Empty);
        }

        public MyClass()
        {
            OnCreating();
        }

        public void Dispose()
        {
            OnDisposing();
        }

        public static void RemoveSubscriptions()
        {
            // Setting the events to null can only be done from within the class. From the outside only += and -= are allowed.
            Creating = null;
            Disposing = null;
        }
    }
}

但是,我不建议采用静态事件方法。为什么? - 因为在使用静态事件时你必须非常非常。如果不明确删除处理程序,则将使托管等效于内存泄漏。它可能会产生不可预测的行为。你不希望这样; - )

我的建议是最安全的选择,例如 Autofac 并在此过程中获得其他几个好东西;-)
但是,它不会处理实例的处理时间。 - 你有什么理由想听那个事件吗?