在C#中,多重继承的替代解决方案有哪些最佳实践?

5

我有一些继承自现有的Windows控件类,例如TextBox和DateTimePicker等等

我想为这些类添加自定义功能,例如(读取、提醒等等)这些添加的功能在所有这些类中都相同

问题是:这些类继承自不同的父类,因此我不能将我的添加功能放入父类中

在这种情况下,最佳做法是什么:

  • 在每个继承的类中重复代码

  • 使用一个分离的类来作为静态方法的功能集合,并从接口中传递参数,为这些类实现该接口并将它们传递。

  • 使用一个分离的类,像第二种方法那样,但使用动态参数(C# 4.0中新增的),或者其他方法!

提前致谢

4个回答

12

我会考虑选项4:组合。

首先,定义您的功能集。我们假设您的部分列表是排他的,因此为“读取”和“警报”。

其次,创建一个实现此功能的单个类,例如MyCommonControlBehaviors。如果可能,我更喜欢此实现不是静态的,尽管它可能是通用的。

public MyCommonControlBehaviors
{
    public Whatever Read() { /* ... */ }
    public void Alert() {}
}

第三步,使用组合将该类的一个实例添加到您的每个自定义控件类型中,并通过您的自定义控件公开该功能:

public class MyCustomControl
{
    private MyCommonControlBehaviors common; // Composition

    public Whatever Read() { return this.common.Read(); }
    public void Alert() { this.common.Alert(); }
}

根据具体情况,您可以创造性地达到必要的程度。例如,也许您的自定义行为需要与私有控件数据交互。在这种情况下,使您的控件实现一个共同的ICommonBehaviorHost接口,您的公共行为需要使用它。然后,在构造时将控件作为ICommonBehaviorHost实例传递给行为类:

public interface ICommonBehaviorHost
{
    void Notify();
}

public class MyCommonControlBehaviors
{
    ICommonBehaviorHost hst = null;

    public MyCommonControlBehaviors(ICommonBehaviorHost host) 
    {
        this.hst = host;
    }

    public void Alert() { this.hst.Notify(); }  // Calls back into the hosting control
    // ...
}

public class MyCustomControl : ICommonBehaviorHost
{
    private MyCommonControlBehaviors common = null;

    public MyCustomControl() { common = new MyCommonControlBehaviors(this); }
    public Whatever Read() { return this.common.Read(); }
    public void Alert() { this.common.Alert(); }

    void ICommonBehaviorHost.Notify() { /* called by this.common */ }
}

4
结合依赖注入,以最小化系统的耦合性。 - marc_s
+1 @marc_s 真说到了点子上。还有很多其他技术可以用来最小化耦合并增强这种方法的功能。我曾经做过的一件事是将MyCommonControlBehaviors泛型化,以便它可以返回一个MyCustomControl,不管它是什么。(在这个例子中,这样做没有太多意义,但在我所工作的领域中,这样做非常有意义。) - Greg D

6

不是回答问题,但是一个好的建议!+1 - bloparod

1
如果必须这样做,我可能会为每个类创建扩展方法,然后在其他对象中引用这些方法所需的实际代码,所有扩展方法都可以调用它们。
这样代码就不会重复,而且扩展方法使其看起来像应该在对象中的方法一样。
本质上是通过创建静态方法并执行以下操作: Functions.DoSomething(my_Object); 但在面向对象的语言中,我总是更喜欢:my_Object.DoSomething()

0
我建议为这些行为定义一个接口,然后(为了避免重复)在该接口定义上创建扩展方法来实现共享方法。(有点像您的第二个选项,只是使用扩展方法而不是完全静态方法)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接