Countable Objects [Problem NOT of the week]

Long time since the first problem..

This is a problem I've faced lately while developing in C# to have some statistics.

I've created a project that does something (of course !! :D) and created a number of classes with some inheritance tree, where some classes inherit from others, anyway, after that i needed to count the number of instances created from each class...

pretty simple, just add a counter to the class, add increment/decrement methodology in the constructor/destructor.

but.

kind of... I'm lazy to open each class, add those members and add them to the newly created, not new!

So.. let's make use of Inheritances,

Create a base class "Countable Object" where all what you need is a private static dictionary which will hold all the type as a key, count as a value, with a constructor that increments the value of the type created.

 

Class CountableObject 
{ 
 private static Dictionary InstancesCounter = new Dictionary(); 
 public CountableObject() 
 { 
  InstancesCounter[this.GetType()]++; 
 } 
 public ~CountableObject() 
 { 
  InstancesCounter[this.GetType()]--; 
 } 
} 

I didn't include the check if that key exists of not, just to simplify things, but I assure you'll have an exception on running the above snippet ;)

Then... just make all your classes to inherit this class & call the base constructor and you have the numbers!

The Next step where I found the major problem..

How to expose those numbers..

I can make the dictionary public and the numbers is extracted as

int count = CountableObject.InstancesCount[TypeOf(ChildClass)];

with another exception to be handled here :D despite this exposure is not good, and it's a bit complex to be used, one of the side effects will be the following usage

 

 int count = ChildClass.InstancesCount[TypeOf(OtherChildClass)];

where each class will have the count of all instances of all the sibling classes!! and simply I can't hide members from being inherited.

I had an idea to create a public property "Count" in the base class that returns the count of each type, using the polymorphism of "GetType()" as in the incrementing methodology.

but. i couldn't find any method that return the type of the class in a static member. or to be more accurate there is a method that gets the type, but it always returns the base type, where it is declared in..

 

 MethodBase.GetCurrentMethod().DeclaringType 

 

there is another way to get the type using stack trace, but it also gets the base class...

So... any ideas ?! :D :D my proposed solutions was

1-Create the static property in each class to get the count. NO !! that's what I avoided at the beginning !! :D

2-Create a separate class to hold this dictionary. and that what I've done.

class Statistics, and the dictionary is filled by the CountableObject class using a function and to get the Count use a static function

 

 
Class Statistics 
{ 
  public static void IncrementType(Type type); 
  public static void DecrementType(Type type); 
  public static int GetNumberOfInstances(Type type); 
} 

 

so, now I don't need to add the counter variable and its logic to each class i create, just inherit from the CountableObject class, and I have all the statistics... any better idea ?!

Frankly, I don't like the CountableObject class concept. I don't think it's a good design, it's more logical to declare it as an interface, but then you would've to implement it in each class. With inheritance however, you'd have forced this structure on your classes, where the inheritance just reflects a single function or specific behavior that doesn't represent an object "family"/class anymore. I'd go one step further with the Statistics class, and make it responsible for creating all the objects anyway, and get rid of the CountableObject thing. Another solution, make Statistics a singleton, and call AddObject/Increment type count within the countable classes constructor, and another Decrement call in the destructor/dispose method. That would be two lines, and almost transparent to the user. Is there someway to get this from the environment anyway?
mmm. I can't get what structure have been forced by the inheritance, if u mean the count methodology, then I already know that it won't/can't change.. and they still are the "family"/class of countable objects I agree that it would be better to be an Interface, but i don't want to add more code to the classes!! :D and if I you get the Statistics class to be responsible for creating all the objects, it'll be a sort of factory, not statistics. and about your other solution.. thats what i already did, except Statistics class is not a singleton, a class with static Increment/Decrement methods. the most interesting thing that frankly I don't understand you last question :D
I don't think that something countable should be considered a family/class, it describes partial behavior that doesn't describe an entity, and when you're going to design your class hierarchy you'll find it weird to have CountableObject as the base class in your hierarchy instead of Employee, Account or whatever. That's why I think the best way is to get rid of it completely, and use a singleton Statistics class. (which had an AddObject and not Increment/Decrement before your last edit :P I'm WATCHING :D ) My last question was about the environment, can't you get this kind of information from the .NET Framework, or the JVM dynamically in some way? I think it makes sense to ask it "How many objects do you have of that type?". I don't know if it can be done however.
LOOOOL, I didn't edit it as a kind of fixing a mistake :D thats the logic I've already implemented, i just changed it to be more clear, and I forgot to add the decrement function :D :D and if the Employee, Account or whatever are countable, it won't be weird to have CountableObject as their base class and they themselves can be base classes for another countable (some type of employees) class :D. and about the environment, i don't think it exists. w ersalak 3ala language for ur display name :D
<blockquote>and if the Employee, Account or whatever are countable, it won’t be weird to have CountableObject as their base class and they themselves can be base classes for another countable (some type of employees) class .</blockquote> I still don't think it's a good idea design wise, as it's an internal requirement in the program, so I don't think it deserves to be the root of the program's design hierarchy. Also, imagine you need to add something else, like PrintableObject that would return a PostScript representation or something, what would you do then? <blockquote>w ersalak 3ala language for ur display name</blockquote> Well, sometimes I'm too lazy to login :P
I actually agree with the interface idea of Hassan. Another thing, remember that in .Net the destructor of an object is only called by the Garbage Collector just before removing the object from memory, not when the object becomes unreferenced from your program. The GC starts removing unreferenced objects only when there is significant amount of memory that can be gained by doing so. In other words, you never know when the destructor of an object will be called, or whether it will be called at all. If you really need precise statistics, you will have to call GC.Collect at the beginning of GetNumberOfInstances to force the GC to remove unreferenced objects instantaneously.
Yeah, i totally agree about the GC thing !