2

我想创建一个类列表,从中可以在我的表单中构建一个“工具箱”。它归结为一个可能的小部件列表,我可以将它们拖放到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,但感觉有点矫枉过正。做这样的事情的最好方法是什么?甚至可以不实例化类吗?

4

4 回答 4

2

AnIWidget代表一个小部件的实例,因此IWidget[]如果您尚未实例化它们,则不能将其作为 a 传递。Type, 或者Type[]应该没问题 - 它不是“矫枉过正” - 它是描述类型的适当且预期的方式。此外,您可以通过以下方式轻松实例化:

IWidget newInstance = (IWidget)Activator.CreateInstance(someConcreteWidgetType);
于 2012-10-23T11:47:42.100 回答
2

我想创建一个类列表

从字面上看,这根本不可能。

您可以做的是创建对象(实例)列表。这可以是Type您已经尝试过的类,或者您可以为每种类型创建一个辅助类。

 class WidgetHelper<T> where  T : IWidget, new() { }

然后您可能想向IWidget.

于 2012-10-23T11:48:39.380 回答
1

如果你不想使用Type对象,你可以求助于工厂模式:

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);
}
于 2012-10-23T11:54:00.917 回答
1

正如 Marc 所说,使用 Type 很好,您可以使用激活器来创建对象(当您将其放在面板中时)。如果您只想使用静态方法来填充工具箱,所以这里没有类创建,然后使用GetMethod()and 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);
}

这个答案的范围之外是关于使用反射和必须使用字符串来传递方法名称的所有注意事项,这在重构时很脆弱并且没有帮助......请记住这一点。

于 2012-10-23T11:57:01.500 回答