组合框控件接受一个对象作为其集合成员,有没有办法约束该对象实现某个接口(interface)?
所以而不是
public int Add(object item)
我想将 add 方法重写为以下几行
public int Add<T>(T item) : where T : ICustomInterface
我正在编写自己的继承自组合框的自定义控件,但我不太确定如何最好地让自定义组合框仅处理实现特定接口(interface)的项目。
谢谢
最佳答案
您可以使用以下技巧来做到这一点。我发现 RefreshItems()
和构造函数是实现该目标的关键位置。
using System;
using System.Reflection;
namespace WindowsFormsApplication2
{
interface ICustomInterface
{
}
public class ArrayList : System.Collections.ArrayList
{
public override int Add(object value)
{
if (!(value is ICustomInterface))
{
throw new ArgumentException("Only 'ICustomInterface' can be added.", "value");
}
return base.Add(value);
}
}
public sealed class MyComboBox : System.Windows.Forms.ComboBox
{
public MyComboBox()
{
FieldInfo fieldInfo = typeof(System.Windows.Forms.ComboBox.ObjectCollection).GetField("innerList", BindingFlags.NonPublic | BindingFlags.Instance);
fieldInfo.SetValue(this.Items, new ArrayList());
}
protected override void RefreshItems()
{
base.RefreshItems();
FieldInfo fieldInfo = typeof(System.Windows.Forms.ComboBox.ObjectCollection).GetField("innerList", BindingFlags.NonPublic | BindingFlags.Instance);
fieldInfo.SetValue(this.Items, new ArrayList());
}
}
}
也就是说,ComboBox.ObjectCollection 包含一个内部列表。我们所要做的就是覆盖它。不幸的是,我们必须使用反射,因为这个字段是私有(private)的。这是检查它的代码。
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
class MyClass : ICustomInterface
{
}
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
this.myComboBox1.Items.Add(new MyClass());
this.myComboBox1.Items.Add(new MyClass());
//Uncommenting following lines of code will produce exception.
//Because class 'string' does not implement ICustomInterface.
//this.myComboBox1.Items.Add("FFFFFF");
//this.myComboBox1.Items.Add("AAAAAA");
base.OnLoad(e);
}
}
}
关于c# - 如何覆盖 winforms 组合框项目集合以实现特定接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45884121/