2014-01-08 3 views
0

Решено.Перечисление всех экземпляров типа во время выполнения?

Мне было интересно, если кто-нибудь знает, возможно ли во время выполнения получить все созданные типы определенного типа?

Предположим, я хочу перечислить все созданные объекты типа Foo.

public class Foo {} 

var foo1 = new Foo(); 
Foo foo2 = new Foo(); 

IEnumerable<Foo> foos = GetObjects<Foo>(); 
//foos should contain foo1 and foo2 

Если нет прямой способ сделать это, то я мог бы просто сделать базовый тип, который подписывается его сам по строительству в некоторой статической службе, а затем сделать посмотреть, что путь ... Но я чувствую, что это уже должно быть выполнено для работы GC.


Я дал бы большинство из вас правильного ответа, если бы я мог, но так как я не мог, я отдал его первый человек, чтобы ответить.

+0

Почему вы беспокоитесь о распределении памяти? Просто любопытно. – Thraka

+0

Это будет работать на сервере, который работает все время. Поэтому я не хочу, чтобы произошла утечка в квази-памяти, где GC не собирает тонну объектов, о которых я не забочусь. – JohnDoe

+0

У вас возникла проблема с этим в какой-то момент? Вот крутая статья о GC http://blogs.msdn.com/b/dotnet/archive/2012/07/20/the-net-framework-4-5-includes-new-garbage-collector-enhancements- for-client-and-server-apps.aspx – Thraka

ответ

4

Ответил над на форумах MSDN: http://social.msdn.microsoft.com/Forums/vstudio/en-US/f9e984e3-a47b-42b0-b9bd-1f1c55e4de96/getting-all-running-instances-of-a-specific-class-type-using-reflection?forum=netfxbcl

не возможно :(

Хотя они, по крайней мере, дать вам идею создания статического списка, чтобы держать все ссылки типа (при условии ее ваш тип Конечно), добавляемый во время создания.

5

Я боюсь, что нет ничего подобного, что доступно в рамках.

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

public class Foo 
{ 
    private static List<Foo> _instances = new List<Foo>(); 

    public Foo() 
    { 
     _instances.Add(this); 
    } 

    public static IEnumerable<Foo> Instances { get { return _instances; } } 
} 

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

public class Foo 
{ 
    private static List<WeakReference<Foo>> _instances = new List<WeakReference<Foo>>(); 
    public Foo() 
    { 
     _instances.Add(new WeakReference<Foo>(this)); 
    } 

    public static IEnumerable<Foo> Instances 
    { 
     get 
     { 
      foreach(var r in _instances) 
      { 
       Foo instance; 
       if (r.TryGetTarget(out instance)) 
        yield return instance; 
      } 
     } 
    } 
} 
+0

Я не знал о WeakReference, это довольно круто (и удобно). Я, вероятно, буду использовать WeakReference, поэтому у меня нет лишнего выделения памяти ... Спасибо! – JohnDoe

3

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

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

class Foo 
{ 
    public static List<Foo> Instances = new List<Foo>(); 
    public Foo() 
    { 
    Instances.Add(this); 
    } 
    //can be accessed like below 
    Foo.Instances 
} 

Это может помочь решить вашу проблему.

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