2009-07-22 9 views
1

Wie kann ich die Anzahl der Objekte eines Klassentyps innerhalb einer Methode dieser Klasse zählen? Wie kann man es außerhalb einer Klasse tun, ohne die Objekte zu einer Liste hinzuzufügen?Anzahl der Objekte des Klassentyps innerhalb der Klassenmethode

Ich hätte daran gedacht! Vielen Dank! Ich werde es eine Weile unbeantwortet lassen, um zu sehen, ob es einen besseren Weg gibt, weil ich zustimme. Ich wickle nur meinen Kopf um OO. Wenn es Ihnen nichts ausmacht, lassen Sie mich ein wenig mehr erklären und vielleicht gibt es einen besseren Weg überhaupt?

Ich habe eine Objektklasse, die ich 3 Informationen zu, hinzufügen möchten, aber zunächst möchte ich, um durch und stellen Sie sicher, es gibt keine anderen Objekte mit einem der drei Stücke die gleiche, und wenn es , mach für jeden Fall etwas anderes.

Antwort

12

Die einzige Möglichkeit zu erreichen, was Sie suchen, ist eine statische Liste dieser Objekte in der Klasse selbst zu halten. Wenn Sie nur sehen möchten, ob irgendwo eine Instanz vorhanden ist, die nicht als Garbage Collection erfasst wurde, sollten Sie die Klasse WeakReference verwenden. Zum Beispiel ...

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

    public MyClass() 
    { 
     instances.Add(new WeakReference(this)); 
    } 

    public static IList<MyClass> GetInstances() 
    { 
     List<MyClass> realInstances = new List<MyClass>(); 
     List<WeakReference> toDelete = new List<WeakReference>(); 

     foreach(WeakReference reference in instances) 
     { 
      if(reference.IsAlive) 
      { 
       realInstances.Add((MyClass)reference.Target); 
      } 
      else 
      { 
       toDelete.Add(reference); 
      } 
     } 

     foreach(WeakReference reference in toDelete) instances.Remove(reference); 

     return realInstances; 
    } 
} 

Da Sie OO neu sind/.NET, lassen Sie sich nicht die WeakReference Verwendung abschrecken. Die Art der Speicherbereinigung funktioniert durch Referenzzählung.Solange ein Teil des Codes oder eines Objekts Zugriff auf eine bestimmte Instanz hat (dh es liegt innerhalb des Bereichs als Teil einer lokalen, Instanz oder statischen Variable), wird dieses Objekt als lebendig betrachtet. Sobald diese Variable außerhalb des Gültigkeitsbereichs liegt, kann/wird der Müllsammler sie irgendwann sammeln. Wenn Sie jedoch eine Liste aller Referenzen verwalten würden, würden sie niemals außerhalb des Gültigkeitsbereichs fallen, da sie als Referenzen in dieser Liste existieren würden. Die WeakReference ist eine spezielle Klasse ermöglicht es Ihnen, einen Verweis auf ein Objekt beizubehalten, das der Garbage Collector ignoriert. Die Eigenschaft IsAlive gibt an, ob WeakReference auf ein gültiges Objekt verweist, das noch vorhanden ist.

Also, was wir hier tun, ist diese Liste der WeakReference s halten, die für jede Instanz von MyClass verweisen, die erstellt worden ist. Wenn Sie eine Liste von ihnen erhalten möchten, durchlaufen wir unsere WeakReference s und schnappen alle von ihnen, die lebendig sind. Irgendwelche, die nicht mehr am Leben sind, werden in eine andere temporäre Liste gesetzt, so dass wir sie aus unserer äußeren Liste löschen können (so dass die Klasse WeakReference selbst gesammelt werden kann und unsere Liste ohne Grund nicht riesig wächst).

0

Sie könnten eine Art von Referenzzählschema implementieren, obwohl ich nicht sicher bin, warum Sie dies tun möchten. Bei jedem Aufruf von 'neu' können Sie einen Zähler erhöhen, und Sie können dann einen Finalizer definieren, um diesen Wert zu verringern. Es gibt wahrscheinlich eine bessere, robustere Art, das zu tun, das war nur von meinem Kopf.

1

Ich bin nicht genau sicher, was du meinst.

MethodInfo methodInfo = ...; 
MethodBody body = methodInfo.GetMethodBody(); 
int count = body.LocalVariables.Count(variable => variable.LocalType == typeof(DesiredType)); 

Eine andere Möglichkeit: Aber es könnte das sein Der Profiler in Team Suite (und vielleicht auch andere) können Sie sagen:

  • Die Anzahl der Objekte des Typs T in jeder Methode zugeordnet
  • die Anzahl der Bytes in jeder Methode zugeordnet

Edit: Aufgrund des Fehlens eines "dupn "oder" swap n, n + 1 "IL-Anweisung, der Compiler ist gezwungen, Locals zu generieren, die Sie möglicherweise nicht erwarten (die Sie nicht explizit deklariert haben). Der Compiler ist auch frei, Locals wo möglich zu entfernen, wenn die Optimierung aktiviert ist.

+0

Das zählt die Anzahl der Variablen, nicht die Anzahl der Instanzen der Klasse ... –

+0

@Adam: Wenn der Beitrag überhaupt nicht eindeutig ist, müssen Sie einige Dinge erraten. Deshalb habe ich es mit "Ich bin mir nicht ganz sicher, was du meinst" vorangestellt. Es ist richtig, die Anzahl der lokalen Variablen zu zählen, was entweder eine Antwort auf das OP oder ein Hinweis darauf ist, die Dinge umzuschreiben. Es ist nicht "einfach falsch". –

0

Meinen Sie auf eine Weise, die Ihnen erlauben würde, zu verfolgen, wie oft Sie new MyClass() so aufgerufen haben, dass N Instanzen derzeit Speicher belegen, und Sie den Wert von N wissen möchten?

Wenn Sie die Speichernutzung nachverfolgen möchten, verwenden Sie den Debugger, um den Status des Heapspeichers zu sichern. Die Sache ist, die Antwort wird vom GC abhängen und ob es nicht referenzierte Objekte gesammelt hat.

Sie könnten einen Zähler haben, den Sie im Konstruktor inkrementieren, aber wann soll er dekrementiert werden? Die Finalizer laufen in einem anderen Thread, was die Unvorhersehbarkeit dieser ganzen Idee unterstreicht. Es könnte besser sein, IDisposable zu implementieren, um den Zähler zu dekrementieren, und die Objekte benötigen, wenn sie nicht benötigt werden.

Verwandte Themen