[英]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.