2010-03-01 2 views
4

Это, наверное, немой вопрос, но я все равно его спрошу ... Я программирую на C# .NET. У меня есть класс, который содержит нестатический экземпляр EventHandler. Возможно ли инициировать этот EventHandler для каждого экземпляра класса, который существует из статического метода? Я знаю, что это длинный выстрел!Есть ли способ статического метода получить доступ ко всем нестатическим экземплярам класса?

+0

Это довольно запутанно. Похоже, вы хотите вызвать обработчик события экземпляра из любого другого экземпляра типа. Другими словами, каждый экземпляр вызовет обработчик событий для каждого другого экземпляра созданного класса ... это правильно? –

+1

Наблюдатель паттен на помощь? –

+0

Хотя есть ответы, которые могут сработать, вы можете рассмотреть вопрос о расширении вопроса, чтобы описать свой сценарий немного больше; возможно, более элегантное решение, такое как шаблон наблюдателя или даже Rx, если вы можете использовать лицензию GoLive, может быть хорошо подходит для вашей проблемы. –

ответ

5

Вы можете сделать это, но вам нужно создать статическую коллекцию всех объектов:

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. 
     } 
    } 
} 

Вы хотите, чтобы следить за накапливая также могут «Вещи». Убедитесь, что вы удалите их из списка, когда они вам больше не нужны.

+2

... хотя вы можете захотеть сделать их слабыми ссылками вместо ... ...и удалите их, по крайней мере, в финализаторах ... и добавьте remix 'lock()', если ваши Вещи будут созданы на нескольких потоках ... которые вы не знаете заранее в большинстве библиотечных ситуаций ... –

+1

Просто имейте в виду что вы можете создать экземпляр без вызова конструктора: http://stackoverflow.com/questions/296584/c-create-object-instance-without-invoking-constructor –

4

Нет, нет. В принципе, нет возможности найти все экземпляры класса, если вы не написали свой собственный код для этого.

РЕДАКТИРОВАТЬ: Заинтересованность в том, почему это занижено. В любом случае, чтобы добавить немного больше деталей, вам следует избегать необходимости этого. Вы можете сделать свой тип реализации IDisposable, а затем зарегистрироваться в статическом обработчике событий в конструкторе и отменить регистрацию в методе Dispose. Черт, у вас может даже быть финализатор, который сделает это за вас, что будет стоить вам производительности, но, по крайней мере, не будет утечки, если вы не захотите распоряжаться экземпляром.

Однако все это несколько мрачные варианты. Было бы гораздо лучше попытаться перепроектировать, чтобы избежать требования. Возможно, вы можете предоставить нам больше информации о том, что вы пытаетесь сделать, и мы можем придумать обходное решение?

+0

+1 - это причина для редизайна, а не просто кода. Наличие экземпляров класса для подписки на наблюдателя вместо того, чтобы пытаться вызвать статический обработчик событий на каждом из них, имеет немного больше смысла, учитывая ограниченную информацию –

+0

+1 никаких оснований понижать голос. –

1

Вы можете сделать так:

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

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

}} 

После этого вы можете делать все, что вы хотите с экземплярами.

+2

... и у вас будет утечка памяти, если только вы 're * really care *, чтобы всегда быть уверенным, что вы удаляете вещи. О, и поскольку поле является общедоступным, все, что использует его, также должно быть осторожным в синхронизации :( –

+0

Я редактирую, чтобы установить поле как личное. Дэвид хочет сделать что-то со всем экземпляром, поэтому он должен быть осторожным в отношении утечка памяти. –

1

я мог бы неправильно понять, что вы имеете в виду, но это должно быть просто ...

Это главный файл

using System; 
using IdeaClass; 

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

Тогда есть класс Идеи:

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

А потом другой класс.

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

Это вызывает неудачную связь между классом, который вызывает событие и класс со статическим вызовом, но это, кажется, что вы хотите.

Смежные вопросы