Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I factor out the code duplication here?

So, I'd like to hear what you all think about this.

I have a project where three different inheritance paths need to all implement another base class. This would be multiple inheritance and isn't allowed in C#. I am curious how I can implement this without code duplication.

EDIT: I don't own the three classes. The three classes are from 3rd party code. So I cannot make them all extend my base class.

Right now I am using three different classes, each one extending a different base class. Then I have the same code in each of the three abstract classes.

I could use a single interface, but I would still need to duplicate the code.

I could make some kind of static class that implements the code and then reference that in each of the 3 abstract classes. It would eliminate the duplication, but, I am not sure how I feel about this. I could implement Extensions methods on the interface, but then the interface itself would be empty and the extension methods (containing the duplicate code) would be in a totally different file, which seems not quite right. Plus I can't implement properties in extension methods...

How can I factor out the code duplication here?

EDIT, inheritance tree:

class Class1 : 3rdPartyBaseClass1 { }
class Class2 : 3rdPartyBaseClass2 { }
class Class3 : 3rdPartyBaseClass3 { }

I have code I want to be in each of the above Classes, but I cannot add it to the 3rdPartyClasses.

like image 597
Alex Baranosky Avatar asked Dec 03 '22 14:12

Alex Baranosky


2 Answers

Create an interface that Class1, Class2, and Class3 can implement. Then put your code in extension methods so it will apply to all.

interface IMyInterface {
    void Foo();   //these are the methods that these 
        //classes actually have in common
    void Bar();    
}

public class Class1 : 3rdPartyBaseClass1, IMyInterface {
    // whatever

}

public static class IMyInterfaceExtensions {
    public static void CommonMethod(this IMyInterface obj) {
        obj.Foo();
        obj.Bar();
    }
}

public static class Program {
    public static void Main() {
        var instance = new Class1();
        instance.CommonMethod();
    }
}
like image 157
recursive Avatar answered Dec 09 '22 15:12

recursive


OK, you can do something similar to my previous suggestion, and also similar to recursive's suggestion. For the functionality you require in all three of your derived classes, you can create a single Interface along with a single class (call it "Implementer" for kicks) that implements that Interface (and that has the actual code you want executed with each call).

In each of your derived classes, then, you implement the Interface and create a private instance of Implementer. In each of the interface methods, you just pass the call along to the private instance of Implementer. Because Implementer and your derived classes all implement your Interface, any changes you make to the Interface will require you to modify Implementer and the derived classes accordingly.

And all your code is in one place, except for all the lines passings the calls on to the private instance of Implementer (obviously multiple inheritance would be better than this, but you go to war with the army you have, not the army you wish you had).

Update: what about just adding a public instance of your class to each of the derived classes?

public class DerivedClass1 : ThirdPartyClass1
{
    public MyClass myClass = new MyClass();
}

Or if you care who Demeter is and you get paid by LOC:

public class DerivedClass1 : ThirdPartyClass1
{
    private MyClass _myClass = new MyClass();
    public MyClass myClass
    {
        get
        {
            return _myClass;
        }
    }
}

Then you'd just call the MyClass methods like this:

DerivedClass1 dc1 = new DerivedClass1();
dc1.myClass.DoSomething();

This way, we could all go to sleep.

like image 21
MusiGenesis Avatar answered Dec 09 '22 15:12

MusiGenesis