我想创建一个类列表,从中我可以在表单中构建一个“工具箱”。它归结为可以拖放到Panel
的可能小部件列表。这些类将实现相同的接口,并具有一些静态方法来创建列表。
我有一些代码:
public interface IWidget {
Image image { get; }
}
public class Gauge : IWidget, PictureBox {
public static Image image {
get {
return Properties.Resources.gauge;
}
}
}
在表单中,我想放一个这样的数组:
IWidget[] supported_widgets = { Gauge };
并循环遍历它们以创建用户可以选择的工具箱,使用类中的静态方法,而不是通过实例化它们(它们将在Panel
上删除时实例化):
foreach (IWidget w in supported_widgets) {
PictureBox p = new PictureBox();
p.Image = w.getImage();
toolbox.Controls.Add(p);
}
我尝试了System.Type
,但感觉有点矫枉过正。做这样的事情最好的方法是什么?是否可以在没有实例化类的情况下实现?
答案 0 :(得分:2)
IWidget
表示窗口小部件的实例,因此如果尚未实例化它,则无法将其作为IWidget[]
传递。 Type
或Type[]
应该没问题 - 它不是“过度杀伤” - 它是描述类型的适当和预期的方式。此外,您可以通过以下方式轻松实例化:
IWidget newInstance = (IWidget)Activator.CreateInstance(someConcreteWidgetType);
答案 1 :(得分:2)
我想创建一个类列表
字面意思是根本不可能。
您可以做的是创建一个对象列表(实例)。这可以是您已经尝试过的Type
类,也可以为每个类型创建一个帮助类。
class WidgetHelper<T> where T : IWidget, new() { }
然后您可能希望为IWidget
添加更多功能。
答案 2 :(得分:1)
如果您不想使用Type
个对象,可以诉诸the Factory pattern:
public interface IWidgetFactory
{
IWidget makeWidget();
}
public class WidgetFactory<TWidget> : IWidgetFactory where TWidget : IWidget, new()
{
IWidget makeWidget()
{
return new TWidget();
}
}
IWidgetFactory[] supported_widgets = { new WidgetFactory<Gauge>(), new WidgetFactory<Indicator>() };
foreach (IWidgetFactory wf in supported_widgets) {
PictureBox p = new PictureBox();
p.Image = wf.makeWidget().getImage();
toolbox.Controls.Add(p);
}
答案 3 :(得分:1)
使用Type就像Marc所说的那样,你可以使用激活器来创建对象(当你将它放入Panel中时)。如果您只想使用静态方法填充工具箱,因此不在此处创建类,请使用GetMethod()
和Invoke()
:
Type[] supported_widgets = { typeof(Gauge) };
foreach (var w in supported_widgets) {
PictureBox p = new PictureBox();
p.Image = w.GetMethod("getImage").Invoke(null, null);
toolbox.Controls.Add(p);
}
在这个答案的范围之外是关于使用Reflection以及必须使用字符串传递方法名称的所有注意事项,这在重构时很脆弱且没有帮助...请记住这一点。