簡體   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