在我們的C#.NET WinForm應用程序中,我們有一個名爲ControlWithLabel
的自定義控件。我想通過模板將其增強到ControlWithLabel<TControl>
。問題是,我們有數百個檢查如if (something is ControlWithLabel)
,並且測試對象可以是多個派生類型(TextBoxWithLabel,ComboBoxWithLabel等)。我怎樣才能將它轉換爲模板解決方案,而無需重寫每張支票,並將其與每種可能性相乘,如if (something is ControlWithLabel<TextBox>) || (something is ControlWithLabel<ComboBox>) || ... etc ...
?當從協變接口派生時,協變性會丟失
我試着使用一個協變接口,但它並不像我期待的那樣工作。當派生到一般的非模板接口時,接口的協方差會丟失。
public class ControlWithLabel<TControl> : IControlWithLabel<TControl> where TControl : Control, new()
{
public ControlWithLabel()
{
this.Control = new TControl();
this.Label = new Label();
}
public Label Label
{
get;
private set;
}
public TControl Control
{
get;
private set;
}
}
public class ControlWithLabel : ControlWithLabel<Control>, IControlWithLabel
{
}
public interface IControlWithLabel<out TControl> where TControl : Control
{
Label Label
{
get;
}
TControl Control
{
get;
}
}
public interface IControlWithLabel : IControlWithLabel<Control>
{
}
public class TextBoxWithLabel : ControlWithLabel<TextBox>
{
public void SpecialMethodForTextBox()
{
// Special code ...
}
}
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void _buttonTest_Click(object sender, EventArgs e)
{
TextBoxWithLabel textBoxWithLabel = new TextBoxWithLabel();
// this works, but then I need to rewrite and multiply every check
if (textBoxWithLabel is ControlWithLabel<TextBox>)
MessageBox.Show("textBoxWithLabel is ControlWithLabel<TextBox>");
// this is not working, since classes cannot be covariant
if (textBoxWithLabel is ControlWithLabel<Control>)
MessageBox.Show("textBoxWithLabel is ControlWithLabel<Control>");
// this is not working at all
if (textBoxWithLabel is ControlWithLabel)
MessageBox.Show("textBoxWithLabel is ControlWithLabel");
// this works, but then I need to rewrite and multiply every check
if (textBoxWithLabel is IControlWithLabel<TextBox>)
MessageBox.Show("textBoxWithLabel is IControlWithLabel<TextBox>");
// this works, but then I need to rewrite every check
if (textBoxWithLabel is IControlWithLabel<Control>)
MessageBox.Show("textBoxWithLabel is IControlWithLabel<Control>");
// this is not working - covariance is lost!! Why?
if (textBoxWithLabel is IControlWithLabel)
MessageBox.Show("textBoxWithLabel is IControlWithLabel");
}
}
我應該怎麼做才能夠普遍採用if (something is ControlWithLabel)
或if (something is IControlWithLabel)
代替if (something is IControlWithLabel<Control>)
?
耶穌!你是對的!謝謝。我將在單獨的答案中寫入正確的代碼。 –
嗯......但...我怎麼才能使用接口的屬性,當我切換繼承的順序,並在代碼中,我所知道的是事實,該對象是一些ControlWithLabel並具有控件和標籤? –