How can I count the number of objects of a class type within a method of that class? For that matter, how to do it outside of a class without adding the objects to a list?
I should have thought of that! Thanks! I'm gonna leave it unanswered for a little while to see if there is a better way, because I agree. I'm just sortv wrapping my head around OO. If you don't mind let me explain a little more and maybe there is a better way in general?
I have an object class that i want to add 3 pieces of information to, but first I want to cycle through and make sure there are no other objects with any of the three pieces the same, and if there are, do something different for each case.
The only way to accomplish what you're looking for is to keep a static list of these objects in the class itself. If you just want to see if there is an instance somewhere that hasn't been garbage collected, then you'll want to use the WeakReference
class. For example...
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;
}
}
Since you're new to OO/.NET, don't let the WeakReference
use scare you. The way garbage collection works is by reference counting. As long as some piece of code or an object has access to a particular instance (meaning it's within scope as a or as part of a local, instance, or static variable) then that object is considered alive. Once that variable falls OUT of scope, at some point after that the garbage collector can/will collect it. However, if you were to maintain a list of all references, they would never fall out of scope since they would exist as references in that list. The WeakReference
is a special class allows you to maintain a reference to an object that the garbage collector will ignore. The IsAlive
property indicates whether or not the WeakReference
is pointing to a valid object that still exists.
So what we do here is keep this list of WeakReference
s that point to every instance of MyClass
that's been created. When you want to obtain a list of them, we iterate through our WeakReference
s and snatch out all of them that are alive. Any we find that are no longer alive are placed into another temporary list so that we can delete them from our outer list (so that the WeakReference
class itself can be collected and our list doesn't grow huge without reason).
I'm not exactly sure what you mean. But it might be this:
MethodInfo methodInfo = ...;
MethodBody body = methodInfo.GetMethodBody();
int count = body.LocalVariables.Count(variable => variable.LocalType == typeof(DesiredType));
Another possibility: The profiler in Team Suite (and maybe others) can tell you:
- The number of objects of type T allocated in every method
- The number of bytes allocated in each method
Edit: Due to the lack of a "dup
n" or "swap
n, n+1" IL instruction, the compiler is forced to generate locals you might not expect (ones you didn't explicitly declare). The compiler is also free to remove locals where possible when optimization is on.
You could implement some type of reference counting scheme, though I am not sure why you would want to do this. For every call to 'new' you can increment a counter, and you could then define a finalizer to decrement this value. There is probably a better, more robust way to do it, this was just off the top of my head.
Do you mean in a way that would allow you to track how many times you had called new MyClass()
such that there are N instances taking up memory at the moment, and you want to know the value of N?
If you want to track memory usage, use the debugger to dump the state of the heap. The thing is, the answer will depend on the GC and whether it has collected unreferenced objects.
You could have a counter you increment in the constructor, but when to decrement it? Finalizers run in another thread, which underlines the unpredictability of this whole idea. Might be better to implement IDisposable
to decrement the counter, and require the objects to be Disposed when not needed.