2014-02-26 102 views
1

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

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 
    } 
+0

首先**为什么**?可能有更好的方法来实现如果你可以说为什么!顺便说一句你可以触发'静态'事件,使它成为可能:) –

+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; 
0

使用IoC容器如Autofac :-)

我不确定统一,但至少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并在此过程中获得其他好处;-)
但是,它在实例处置时无法处理。 - 任何你想听这个事件的理由?