在我们的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并具有控件和标签? –