将控件作为通用参数类型传递并从中继承

时间:2016-02-07 23:55:52

标签: c# oop generics controls

我有许多自定义控件,它们从现有的Windows窗体控件以及我自己设计的一个或多个界面扩展而来。这些接口的实现在每个自定义控件中几乎完全相同,因此我将重复代码,如下所示:

public class CustomTextBox : TextBox, ISomeInterface
{
    // Implementations of interface members

    ...
}

public class CustomButton : Button, ISomeInterface
{
    // Implementations of interface members

    ...
}

理想情况下,我希望能够做类似以下的事情:

public abstract class BaseCustomControl<C> : C, ISomeInterface where C : Control
{
    // Implementations of interface members
}

public class CustomTextBox : BaseCustomControl<TextBox>
{
    // Implementations of interface members

    ...
}

public class CustomButton : BaseCustomControl<Button>
{
    // Implementations of interface members

    ...
}

这样,我的相同实现将被删除并合并到一个基类中以减少重复代码。不幸的是,这是不可能的;我可以使用任何合适的替代品吗?

2 个答案:

答案 0 :(得分:1)

由于C#不支持多重继承,因此您必须使用合成来获得所需的行为。

定义一对接口;一个是“真正的”接口,另一个只是提供第一个的实例:

public interface ISomeInterface
{
    string Foo { get; }
    void Bar();
}

public interface ISomeInterfaceControl
{
    ISomeInterface SomeInterface { get; }
}

然后创建“真实”界面的实现:

public class SomeInterfaceImpl : ISomeInterface
{
    private Control _control;

    public string Foo { get; private set; }
    public void Bar()
    {
    }

    public SomeInterfaceImpl(Control control)
    {
        _control = control;
    }
}

通过返回“真实”接口实现的实例来修改控件以实现“包装器”接口:

public class CustomTextBox : TextBox, ISomeInterfaceControl
{
    public ISomeInterface SomeInterface { get; private set; }

    public CustomTextBox()
    {
        this.SomeInterface = new SomeInterfaceImpl(this);
    }
}

现在所有逻辑都包含在“SomeInterfaceImpl”类中,但您可以按如下方式访问任何自定义控件的逻辑:

CustomTextBox customTextBox = new CustomTextBox();
customTextBox.SomeInterface.Bar();

如果自定义控件的行为需要变化,则可以为ISomeInterface引入并行继承层次结构:

public class TextBoxSomeInterface : SomeInterfaceImpl
{
    public TextBoxSomeInterface(CustomTextBox textBox)
        : base(textBox)
    {
    }
}

public class ButtomSomeInterface : SomeInterfaceImpl
{
    public ButtomSomeInterface(CustomButton button)
        : base(button)
    {
    }
}

并像这样使用它:

public class CustomTextBox : TextBox, ISomeInterfaceControl
{
    public ISomeInterface SomeInterface { get; private set; }

    public CustomTextBox()
    {
        this.SomeInterface = new TextBoxSomeInterface(this);
    }
}

答案 1 :(得分:0)

您可以查看extension methods

作为一个例子

// This would be your interface method
public static bool IsHigh(this Control mySelf) {
    return mySelf.Height > 100;
}

如果你的课程扩展Control(或其中一个子类),你可以简单地调用这样的方法:

CustomTextBox tb = new CustomTextBox();
if (tb.IsHigh()) ...