How can I cancel duplicate code here?

So, I would like to hear what you all think about it.

I have a project in which three different inheritance paths should implement a different base class. This will be multiple inheritance and not allowed in C #. I am curious how I can implement this without duplicating code.

EDIT: I do not own three classes. Three classes relate to third-party code. Therefore, I cannot force them to extend the base class.

Now I use three different classes, each of which extends a different base class. Then I have the same code in each of the three abstract classes.

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

I could make some kind of static class that implements the code, and then refers to what is in each of the three abstract classes. This will eliminate duplication, but I'm not sure how I feel about it. I could implement extension methods on the interface, but then the interface itself would be empty, and the extension methods (containing duplicate code) would be in a completely different file, which seems not quite right. Plus, I cannot implement properties in extension methods ...

How can I cancel duplicate code here?

EDIT, inheritance tree:

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

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

+4
source share
5 answers

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

 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(); } } 
+6
source

Well, you can do something similar to my previous sentence, and also like a recursive sentence. For the functionality that you require in all three derived classes, you can create a single interface together with one class (call it the β€œexecutor” for beats) that implements this interface (and which has the actual code that you want to execute on every call )

In each of your derived classes, you implement an interface and create a private instance of the executor. In each of the interface methods, you simply pass the call along with a private instance of Implementer. Since the implementation and your derived classes implement your interface, any changes you make to the interface will require you to modify the executor and the derived classes accordingly.

And all your code is in one place, with the exception of all the line passes that are called to a private copy of the artist (obviously, multiple inheritance would be better than that, but you go to war with the army you have, and not with the army that you would like to have).

Update : how easy is it to add a public instance of your class to each of the derived classes?

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

Or, if you are interested in who Demeter is, and you get LOC:

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

Then you simply call the MyClass methods as follows:

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

So we could all sleep.

+5
source

Similar to the MusiGenesis suggestion , if you need functionality for third-party classes but don't have to go down from them, you can use the following composition:

 class ThirdPartyBaseClass1 { public void DoOne() {} } class ThirdPartyBaseClass2 { public void DoTwo() { } } class ThirdPartyBaseClass3 { public void DoThree() { } } abstract class Base { public void DoAll() { } } class Class1 : Base { public void DoOne() { _doer.DoOne(); } private readonly ThirdPartyBaseClass1 _doer = new ThirdPartyBaseClass1(); } class Class2 : Base { public void DoTwo() { _doer.DoTwo(); } private readonly ThirdPartyBaseClass2 _doer = new ThirdPartyBaseClass2(); } class Class3 : Base { public void DoThree() { _doer.DoThree(); } private readonly ThirdPartyBaseClass3 _doer = new ThirdPartyBaseClass3(); } 

It also gives you the freedom to define any interfaces you want and implement them in your classes.

+4
source

It looks like you need to insert a new abstract class into the inheritance tree at any point where these three paths come together, but in fact there is not enough information. If you could publish part of your inheritance tree, that would help a lot.

+1
source

I think you can use composition instead of inheritance. Exactly how to do this depends on how the third-party classes look and how your own code looks. More specific code related to your problem will be useful, but, for example, suppose you want to have three different third-party GUI widgets that you all need to configure using your own initializer code.

Case 1: Suppose your third-party widgets look like this:

 public interface IThirdPartyWidget { public void doWidgetStuff(); } public class ThirdPartyWidget1: ThirdyPartyWidget implements IThirdPartyWidget { ... } public class ThirdPartyWidget2: ThirdPartyWidget implements IThirdPartyWidget { ... } 

You can do:

 public class MyWidget implements IThirdPartyWidget { private IThirdPartyWidget delegateWidget; public MyWidget(IThirdPartyWidget delegateWidget) { this.delegateWidget = delegateWidget; } public void doWidgetStuff() { delegateWidget.doWidgetStuff(); } } 

Case 2: Suppose you absolutely need to extend these widgets, and you need to reorganize your own code:

 public class MyWidget1: ThirdPartyWidget1 { public void myMethod() { runMyCode(); } private void runMyCode() { //something complicated happens } } public class MyWidget2: ThirdPartyWidget2 { public void myMethod() { runMyCode(); } private void runMyCode() { //something complicated happens } } 

It can become:

 public class MyCodeRunner { public void runMyCode() { //... } } public class MyWidget1: ThirdPartyWidget1 { private MyCodeRunner myCode = new MyCodeRunner(); public void myMethod() { myCode .runMyCode(); } } public class MyWidget2: ThirdPartyWidget2 { private MyCodeRunner myCode = new MyCodeRunner(); public void myMethod() { myCode .runMyCode(); } } 

Hope this makes sense!

+1
source

All Articles