繁体   English   中英

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

[英]Passing a control as a generic parameter type and inheriting from it

我有许多自定义控件,这些控件从现有的Windows Forms控件以及我自己设计的一个或多个接口扩展而来。 这些接口的实现在每个自定义控件中实际上是相同的,因此我将重复以下代码:

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

    ...
}

这样,我相同的实现将被删除并合并为一个基类,以减少重复代码。 不幸的是,这是不可能的。 有什么合适的替代方法可以使用吗?

由于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);
    }
}

您可以研究扩展方法

举个例子

// 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()) ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM