C#:创建一个类数组
我想创建一个类列表,从中可以在表单中构建一个“工具箱”。它归结为一系列可能的小部件,我可以将它们拖放到C#:创建一个类数组,c#,class,C#,Class,我想创建一个类列表,从中可以在表单中构建一个“工具箱”。它归结为一系列可能的小部件,我可以将它们拖放到面板中。这些类将实现相同的接口,并具有一些静态方法来创建列表 我有一些代码: public interface IWidget { Image image { get; } } public class Gauge : IWidget, PictureBox { public static Image image { get { return P
面板中。这些类将实现相同的接口,并具有一些静态方法来创建列表
我有一些代码:
public interface IWidget {
Image image { get; }
}
public class Gauge : IWidget, PictureBox {
public static Image image {
get {
return Properties.Resources.gauge;
}
}
}
在表单中,我想放置如下数组:
IWidget[] supported_widgets = { Gauge };
并循环使用它们来创建工具箱,用户可以从中选择,使用类中的静态方法,而不是通过实例化它们(当将它们放到面板上时,它们将被实例化)
:
我尝试了System.Type
,但感觉有点过头了。做这样的事情最好的方法是什么?甚至可以不实例化类吗?一个IWidget
表示一个小部件的实例,因此如果您还没有实例化它们,就不能将其作为IWidget[]
传递<代码>类型
,或类型[]
应该可以-这不是“过度使用”-这是描述类型的适当且预期的方式。此外,您可以通过以下方式轻松实例化:
IWidget newInstance = (IWidget)Activator.CreateInstance(someConcreteWidgetType);
我想创建一个类列表
从字面上看,这根本不可能
您可以做的是创建对象(实例)列表。可以是您已经尝试过的类型
类,也可以为每个类型创建一个帮助器类
class WidgetHelper<T> where T : IWidget, new() { }
类WidgetHelper,其中T:IWidget,new(){}
然后,您可能需要向IWidget添加更多的功能 如果不想使用
类型
对象,可以求助于
公共接口IWidgetFactory
{
IWidget makeWidget();
}
公共类WidgetFactory:IWidgetFactory其中TWidget:IWidget,new()
{
IWidget makeWidget()
{
返回新的TWidget();
}
}
IWidgetFactory[]支持的_widgets={new WidgetFactory(),new WidgetFactory()};
foreach(受支持的_小部件中的IWidgetFactory wf){
PictureBox p=新PictureBox();
p、 Image=wf.makeWidget().getImage();
工具箱.控件.添加(p);
}
正如Marc所说,使用Type很好,您可以使用activator创建对象(当您将其放入面板时)。如果只想使用静态方法填充工具箱,因此此处不创建类,请使用
GetMethod()
和Invoke()
:
在这个答案的范围之外是关于使用反射和必须使用字符串来传递方法名的所有考虑事项,这是脆弱的,在重构时没有帮助。。。请记住这一点。接口应以I<代码>IWidget与
小部件相对。它使阅读代码更容易理解什么是接口,什么是类。@m-y我知道。我将更新我的问题。另外,您不能将接口公共成员实现为静态成员。它必须作为一个实例来实现。顺便问一下,您有什么理由不想实例化这些类吗?我正在查看您的代码示例,类看起来相当小,因此实例化应该很便宜。@Mihai唯一的原因是我总是尽量避免不必要的事情。我同意在这个例子中,类很小,但我不知道以后会发生什么。当使用Type
时,我应该使用GetMember()
来获取图像
?@BartFriederichs no;“静态图像”是个坏主意。在这种情况下,Mihai答案中的工厂场景更有意义。是的,但这将实例化该类。这就是我想要避免的。我的缺点——我只是注意到getImage
是类的静态方法。
class WidgetHelper<T> where T : IWidget, new() { }
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);
}
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);
}