1

Probem: A parent abstract class must be aware of all his existing child classes. The parent class must also be able to list all the class names of his child classes through a method.

Context: In my situation, the parent class is used to represent any input data type for a web form (such as email, text, boolean, integer, image, and so on). The child classes represent each specific data types. So there is a Boolean class, an Image class, an Integer class, etc.

The language I'm using is C#.

How would you do that?

edit: The reason why I need to know the child classes is because I need to know all the input data types available in order to list them. Also, I need to access the methods of each data type (child class) to get its properties.

So, for example, I need to get an instance of the Image class simply with the string "Image" that is stored in a database. If the base class knowns all its children, I will be able to ask it to get me the child represented by the string "Image", and it will return an instance of the Image class.

I thought of implementing it by making each child a Singleton, and adding itself to a list of children (at construction) that would be a private field of the base DataType class.

  • 4
    Can you elaborate what is the reason that the parent has to know all its descendants? – Frank Aug 18 '10 at 16:39
  • 1
    But *why* does your base class need to know about those subclasses? You can get this info through AppDomain.CurrentDomain.GetAssemblies().GetTypes().Where(x => typeof(YourBaseClass).IsAssignableFrom(x)), but I don't think you should in this case. – Kirk Woll Aug 18 '10 at 16:40
  • I'd say your going about the problem the wrong without knowing why you're abstract class needs to know about its descending classes. – Roman Aug 18 '10 at 16:41
  • @Kirk why don't you think he should in this case? – Jaime Garcia Aug 18 '10 at 16:42
  • 4
    This has a 'bad code smell'.... that's why he almost certainly shouldn't do it in this or any case – James Gaunt Aug 18 '10 at 16:44
  • Sounds like you should be using interfaces more, and classes less...? – CaffGeek Aug 18 '10 at 16:48
  • I'll second (or third) the "bad code smell." Perhaps if you elaborate on what you're trying to achieve, someone can suggest a better way to go about it. – quentin-starin Aug 18 '10 at 16:49
  • I had a similar requirement in my question @ http://stackoverflow.com/questions/2002716/c-abstract-strategy-base-class-serving-as-abstract-factory-for-strategy-objects. I guess using big words in my title makes it more acceptable. – DonaldRay Aug 18 '10 at 17:46
  • Given that I won't have more than 10-20 subclasses, I simply manually added the instance of each subclass (they are singletons) to a list contained in the base class (I did it in the static constructor of the base class). It's working well now and the base class knows every instance of its subclasses. –  Aug 18 '10 at 18:25

4 Answers4

1

Making a parent aware of its children is a strong code smell. It introduces a nasty type of circular dependency. It treads on the Dependency Inversion Principle (depend on abstractions, not concretions) about as blatantly as possible (making an abstract class actually depend on concrete implementations of itself). It does away with the separation of concerns which is at the heart of inheritance.

In short, you should be in for a redesign. I would have to know more of the problem context to give specific advice on that.

Keith Pinson
  • 7,835
  • 7
  • 61
  • 104
1

Sorry to resurrect this but I think what you are looking for is a factory that is aware of all of the implementations, not a base class that is aware of all of its children. The factory would basically know all types that it can construct based on the string.

Forgive me because I'm not too familiar with C# syntax anymore, but it would be something like the following:

public class Control // (could be base class or whatever is needed)
{

}

public class ImageControl extends Control
{

}

public class ControlFactory
{
    public static Control createControl(String control)
    {
        if(control == "IMAGE")
        {
            return new ImageControl();
        }
        // error situation, control was unknown.
    } 
}

Like other people have commented, a parent knowing about its children is typically a really bad idea.

dsingleton
  • 976
  • 6
  • 7
1

You can check out this post. Looks like you need to iterate through known types and see if they are a subclass of the parent class using Type.IsSubclassOf

Community
  • 1
  • 1
SwDevMan81
  • 48,814
  • 22
  • 151
  • 184
  • Thank you, I didn't know this way of doing it. For sure it would work, even though the cost if this operation seems a bit heavy. –  Aug 18 '10 at 17:44
1

You can write in the constructor code that will notify some static class that something new was created.

Something like:

class A {
 A() {
  myBuilder.notifyMe(this);
 }
}

myBuilder is a static class with code:

void notifyMe(Object o) {
 // do whatever you want here
 // maybe something like
 someList.Add(typeof(o).Name)
}

edit: Ok, this solution, of course, requires that the subclasses are instantiated first. If you want to know all the subclasses when program starts I think the only way is to scan entire class path and check for each class is it subclass of wanted one.

Klark
  • 8,162
  • 3
  • 37
  • 61
  • 1
    This is not really an answer to the OP's question. This requires that the subclasses be instantiated first, which is probably not what he wants, and certainly not what he asked for. – Kirk Woll Aug 18 '10 at 16:48
  • Well this is how I initialy thought of implementing it. I tried to make each subclass a singleton in order to have them notify the static class automatically upon their unique construction, but it isn't working. –  Aug 18 '10 at 17:40
  • well they do not need to be singletons. Builder can have some hash map and every time when some class is created it will check in the hash is it already there and if it is not then that is the first instance of that class and you can do whatever logic you want. Give us your code, maybe someone will help you, – Klark Aug 18 '10 at 17:57