如何在这里分解代码重复?

Ale*_*sky 4 c# inheritance refactoring design-patterns multiple-inheritance

所以,我想听听大家对此的看法.

我有一个项目,其中三个不同的继承路径需要全部实现另一个基类.这将是多重继承,在C#中是不允许的.我很好奇如何在没有代码重复的情况下实现这一点.

编辑:我不拥有这三个班级.这三个类来自第三方代码.所以我不能让它们都扩展我的基类.

现在我使用三个不同的类,每个类扩展一个不同的基类.然后我在三个抽象类中的每一个中都有相同的代码.

我可以使用单个界面,但我仍然需要复制代码.

我可以创建一些实现代码的静态类,然后在3个抽象类中的每一个中引用它.它会消除重复,但是,我不确定我对此的看法.我可以在接口上实现Extensions方法,但接口本身将是空的,扩展方法(包含重复的代码)将在一个完全不同的文件中,这似乎不太正确.另外,我无法在扩展方法中实现属性...

如何在这里分解代码重复?

编辑,继承树:

class Class1 : 3rdPartyBaseClass1 { }
class Class2 : 3rdPartyBaseClass2 { }
class Class3 : 3rdPartyBaseClass3 { }
Run Code Online (Sandbox Code Playgroud)

我有代码,我想要在上面的每个类中,但我不能将它添加到3rdPartyClasses.

rec*_*ive 6

创建Class1,Class2和Class3可以实现的接口.然后将您的代码放在扩展方法中,以便它适用于所有.

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();
    }
}
Run Code Online (Sandbox Code Playgroud)


Mus*_*sis 5

好的,你可以做一些类似于我之前的建议,也类似于递归的建议.对于所有三个派生类所需的功能,您可以创建一个单独的接口以及一个实现该接口的类(称为"实施者",用于踢)(并且具有您希望在每次调用时执行的实际代码) ).

然后,在每个派生类中,实现接口创建Implementer的私有实例.在每个接口方法中,您只需将调用传递给Implementer的私有实例.由于Implementer和派生类都实现了您的接口,因此您对接口所做的任何更改都需要您相应地修改Implementer和派生类.

并且你的所有代码都在一个地方,除了所有的行传递调用到实现者的私有实例(显然多重继承将比这更好,但你与你拥有的军队,而不是你想要的军队开战你有过).

更新:如何将类的公共实例添加到每个派生类?

public class DerivedClass1 : ThirdPartyClass1
{
    public MyClass myClass = new MyClass();
}
Run Code Online (Sandbox Code Playgroud)

或者如果您关心Demeter是谁并且您通过LOC获得报酬:

public class DerivedClass1 : ThirdPartyClass1
{
    private MyClass _myClass = new MyClass();
    public MyClass myClass
    {
        get
        {
            return _myClass;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你只需要像这样调用MyClass方法:

DerivedClass1 dc1 = new DerivedClass1();
dc1.myClass.DoSomething();
Run Code Online (Sandbox Code Playgroud)

这样,我们都可以去睡觉了.