0

I have a BaseClass, which implements a method to populate itself form a different data structure. SubClasses will add their properties to the base ones. I want all sub-classes and sub-sub...classes to implement their own version of the method and call their parent class to do the same. So this is not just overriding, I want to force the implementation, but each implementation of the method has to be called, not just overridden.

Sort of like:

class BaseClass
{
 int id;
 virtual void fromDictionary(Dictionary data)
 {
   id = data["id"];
 }
}

class Derived1 : BaseClass
{
 string name;
 override void fromDictionary(Dictionary data)
 {
   name = data["name"];
   base.fromDictionary(data);
 }
}

class Derived2 : Derived1
{
 float size;
 override void fromDictionary(Dictionary data)
 {
   size = data["size"];
   base.fromDictionary(data);
 }
}

Then doing this:

Derived2 object = new Derived2();
object.fromDictionary(dictionary);

Populates all of the object's properties.

I can make the first one virtual and override in the derived ones, but that doesn't force the implementation. And making an abstract base above this base or using an interface wouldn't force ALL levels of inheritance to implement.

The ideal case would be forcing all derived classes to implement their version AND call their parent's version (or even better, have some sort of extension/overriding that automatically calls ALL implementations of the method from the instantiated object's class upwards).

How close to that can I get ?

meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
mikepa88
  • 733
  • 1
  • 6
  • 20
  • Classes Derived1 and Derived2 are not deriving from BaseClass. Are you missing anything? – Chetan Apr 03 '17 at 10:28
  • 1
    Sounds like you want the template method pattern. Search on Stack Overflow for various examples. (I'd also strongly advise you to write real code rather than pseudocode, e.g. using the generic dictionary type properly, and follow .NET naming conventions.) – Jon Skeet Apr 03 '17 at 10:28
  • oh yeah i forgot to add it, gonna edit – mikepa88 Apr 03 '17 at 10:28
  • http://stackoverflow.com/questions/4118925/automatically-call-base-method – CodeCaster Apr 03 '17 at 10:28
  • If you're eager to switch languages then you may want to consider Rust. If you're bound to C# then your may try to somehow implement strategy (or template as mentioned above) pattern and take common logic out to another method that would be hard coded. With all that said - it's not possible to achieve what you want in C# using purely language constructs. – Sergey.quixoticaxis.Ivanov Apr 03 '17 at 10:29
  • Some pseudo code: `public Call() { CallBaseLogic(); CallDerivedCustomizationLogic(); } private CallBaseLogic() { // do something what you want for your base to always do} protected abstract CallDerivedCustomizationLogic(); // it would force children to customize base logic with their own` – Sergey.quixoticaxis.Ivanov Apr 03 '17 at 10:33
  • 1
    @Sergey.quixoticaxis.Ivanov but it will not force children of those children to call base method, unless children do the same. And you have no control of children. – Evk Apr 03 '17 at 10:42
  • @Evk oh, I see, I misread the original author of the question. He/she wants to call all parents recursively. Hmmm... I can't think of a way to implement it in C# =) – Sergey.quixoticaxis.Ivanov Apr 03 '17 at 10:53
  • @Jon Skeet Ok, template method pattern seems right. But can I call the instantiated class parent method in the base class template method? That way, I could make all classes call their parent after doing their part. But I can't call base.method() in the base class and expect it to call the instantiated object's class parent method. – mikepa88 Apr 03 '17 at 11:17
  • Maybe I'm not explaining properly. I would like to do: `Derived2 object = new Derived2(); object.fromDictionary(data)` And in the baseClass: `fromDictionary(){ fromDictionaryOperation(); if(not base) base.fromDictionary(); }` But base.fromDicitionary() in the baseclass means the parent of the Derived2 object implementation (not the parent of the baseClass, that doesn't exist) – mikepa88 Apr 03 '17 at 11:19
  • You don't make the subclass call the base class. You have a separate abstract method in the base class, and clients call the base class method which calls the abstract method and then does whatever else it needs to do. – Jon Skeet Apr 03 '17 at 12:23
  • @Jon Skeet I need to make every class call its parent, because every class adds its own in the overall functionality of the method. And I want to force ALL children and grandchildren to implement it. If I use an abstract in the base class, then only its children will be force to implement it, not the children of those, right? Maybe that could be solved by using an interface for all children with the method in it. But then the last thing is, is there any way to force all the implementations of the method in all the levels to be executed when calling the most derived one? – mikepa88 Apr 03 '17 at 13:39
  • @Jon Skeet Also, I'm thinking if the Template method pattern really is useful here. As I understand it, it helps when deferring part of a functionality to subclasses. But it's not the case exactly. I need each derivation to add its part to all the previous parts. Correct me if I'm rong, but using template method pattern I would still need to call `base.fromDictionary(data)` in each class, and it would be the same as having `abstract void fromDictionary(data)` in the base and forcing only the first child to implement it. – mikepa88 Apr 03 '17 at 13:50
  • Ah, I see - I'd missed that this was multiple inheritance layers. Apologies. I don't know any language feature to support this: I'd enforce it simply by testing carefully. (Or redesign to use composition instead of inheritance, if feasible.) – Jon Skeet Apr 03 '17 at 14:18
  • Ok I was wrong, there is a use for the template pattern even in this case, cause it forces implementation AND provides an unavoidable basic implementation. BUT, still that doesn't go further than ONE derivation. I still can't figure a way to make it work with multiple levels while forcing each one to call base.fromDictionary(). – mikepa88 Apr 03 '17 at 14:19
  • @Jon Skeet thank you for the suggestions. Have a nice day! – mikepa88 Apr 03 '17 at 15:15

2 Answers2

1

Seeing why you need this kind of overriding I strongly believe that you should try to move this logic to a constructor because as it looks now:

Derived2 object = new Derived2();
object.fromDictionary(dictionary);

Your object will only be valid if it has a dictionary. So instead of constructing it from a dictionary using a method, you should provide a constructor which receives a dictionary as a parameter:

Derived2 object = new Derived2(dictionary);

Now you have a valid object from the beggining. There are more reasons why you should do this instead of using a method which composes your object, one as you observed is that each subclass will need to call the base method, and having this kind of constructor (assuming that you will not provide a parameterless one) will force the inheritors to call the base one.

Another advantage in using this kind of approach is that you will have a valid object form the beginning instead of making it possible for users of that classes to make invalid objects by forgetting to call the fromDictionary() method.

meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
  • wow, I don't know why I think of that sooner. I guess the method started off as a static method and then I just forgot to put the functionality in the constructor when it went back to being non-static. That works fine now, because having only that implementation of the base constructor means I always have to call it from each derivation or else it fires an error. The only problem would come when I need to have other constructors, but for the moment I don't need that. Class can even be created from a Json sent to the webservice. THANK YOU! – mikepa88 Apr 03 '17 at 16:17
0

Thanks for the suggestions everyone, the closest I could get is:

public abstract class DAO
{
    public long id { get; set; }

    public void fromDictionary(Dictionary<string, object> obj)
    {
        //Does own part in the method
        id = (long)obj["id"];

        //Calls most derived implementation
        fromDictionaryOperation(obj); 
    }

    //Forces child to implement its part
    protected abstract void fromDictionaryOperation(Dictionary<string, object> obj);
}

//Is forced to implement its part, and the base implementation will be executed always
public class Area : DAO
{
    public string name { get; set; }
    protected override void fromDictionaryOperation(Dictionary<string, object> obj)
    {
        name = (string)obj["name"];
    }
}

//Is NOT forced to implement method, and MUST call base.fromDictionary() for all this to work properly, but is NOT FORCED TO.
public class CircularArea : Area
{
    public float radius { get; set; }
    protected override void fromDictionaryOperation(Dictionary<string, object> obj)
    {
        radius = (float)obj["radius"];
        base.fromDictionary(obj);
    }
}

So all 2nd generation classes will be fine, but subsequent sub-classes wont be forced to implement its part or call the parent implementation. Which means that if in an implementation of a sub-sub-class, the base.fromDictionary() method is not called, then all parent classes implementation, except the first/base class, will be skipped without any compiling warning or error. To force implementation at all levels, I guess I could put the abstract method in an Interface and make all classes implement the interface, which can't be forced itself, but is as close as I can think of.

If anyone knows a way to completely force ALL of them to implement the same method, that would be top notch.

meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
mikepa88
  • 733
  • 1
  • 6
  • 20
  • You could probably use [reflection](http://stackoverflow.com/a/2932448/703644) to cause run time issues, if it is that important that children implement their own method. – TheNorthWes Apr 03 '17 at 15:17