views:

141

answers:

4

This is probably a dumb question but I'm going to ask it anyways... I am programing in C#.NET. I have a class that contains a non-static, instance EventHandler. Is it possible to trigger that EventHandler for every instance of the class that exists from a static method?? I know this is a long shot!

+4  A: 

No, there isn't. Basically there's no way to find all instances of a class, unless you write your own code to do that.

EDIT: Intrigued as to why this is downvoted. Anyway, to add a bit more detail: you should avoid needing to do this. You could make your type implement IDisposable, then register against a static event handler in the constructor, and unregister in the Dispose method. Heck, you could even have a finalizer to do that for you, which will cost you performance but at least not leak if you fail to dispose of the instance.

All of these are somewhat grim options, however. It would be far better to try to redesign so as to avoid the requirement. Perhaps you can give us more information about what you're trying to do, and we can come up with a workaround?

Jon Skeet
+1 - this is cause for a redesign, not just more code. Having instances of the class subscribe to an observer rather than trying to call a static eventhandler on each makes a bit more sense given the limited info
Rob Allen
+1 no reason to down vote this.
Brian Rasmussen
+4  A: 

You can do this, but you'll need to create a static collection of all your objects:

public class Thing
{
   public static List<Thing> _things = new List<Thing>();

   public Thing()
   {
       _things.Add(this);
   }

   public static void SomeEventHandler(object value, EventHandler e)
   {
      foreach (Thing thing in _things)
      {
           // do something.
      }
   }
}

You'll want to watch out for accumulating too may "Things" . Make sure you remove them from the list when you don't need them anymore.

David Morton
...though you may want to make them weak references instead... ...and remove them at least in finalizers... and add remi's `lock()` if your Things will be created on multiple threads... which you don't know in advance in most library situations...
Pontus Gagge
Just keep in mind that you can create an instance without calling the constructor: http://stackoverflow.com/questions/296584/c-create-object-instance-without-invoking-constructor
Brian Rasmussen
+1  A: 

You can do like this :

    public class MyClass{
private static List<MyClass> Instances = new List<MyClass>();

    public MyClass(){
lock(typeof(MyClass)){
Instances.Add(this);
}

}}

After this you can do what ever you want with Instances.

remi bourgarel
... and you'll have a memory leak unless you're *really careful* to always make sure you remove things. Oh, and as the field is public everything using it will have to be careful of the synchronization as well :(
Jon Skeet
I edit to set the field as private. David want to do something to all the instance so he have to be careful about the memory leak.
remi bourgarel
+1  A: 

I could be wrong in understanding what you mean, but it should be simple...

This is the main file

using System;
using IdeaClass;

namespace TestIdeas
{
    class Program
    {
        static void Main(string[] args)
        {
            Ideas i = new Ideas();
            Ideas.triggerMany();
            Console.ReadLine();
        }
    }
}

Then there is the Ideas class:

using System;

namespace IdeaClass
{
    public class Ideas
    {
        static OtherClass oc = new OtherClass();
        public static void triggerMany()
        {
            oc.runThing("textual");
        }

        public Ideas()
        {
            Ideas.oc.ThingEvent += DoThingHandler;
        }

        public void DoThingHandler(string thing)
        {
            System.Console.WriteLine(thing);
        }
    }
}

And then the other class.

using System;

namespace IdeaClass
{
    class OtherClass
    {
        public delegate void DoThing(string text);
        public event DoThing ThingEvent;

        public void runThing(string text)
        {
            if (ThingEvent != null)
            {
                ThingEvent(text);
            }
        }
    }
}

It does cause unfortunate coupling between the class that raises the event and the class with the static call, but it seems to do what you want.

Matt Ellen