2012-10-23 94 views
2

我想創建一個類的列表,我可以在其中創建一個「工具箱」在我的窗體中。它歸結爲一個可能的小部件列表,我可以拖放到Panel。這些類將實現相同的接口並有一些靜態方法來創建列表。C#:創建一個類的數組

一些代碼,我有:

public interface IWidget { 
    Image image { get; } 
} 

public class Gauge : IWidget, PictureBox { 
    public static Image image { 
     get { 
      return Properties.Resources.gauge; 
     } 
    } 
} 
在Form

,我想提出一個這樣的數組:

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

接口應該以I ...'IWidget'開始,而不是'Widget'。它使閱讀代碼更容易理解什麼是接口和什麼是類。 –

+0

@ m-y我知道。我會更新我的問題。 –

+3

另外,您不能將接口公共成員實現爲靜態。它必須作爲一個實例來實現。 –

回答

2

我想創建的類

採取列表字面上是根本不可能的。

你可以做的是創建一個對象列表(實例)。這可以是您已經嘗試的Type類,或者您可以爲每個類型創建一個輔助類。

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

,然後你可能要多一點功能添加到IWidget

2

IWidget表示小部件的一個實例,因此如果您尚未實例化它們,則無法將其作爲IWidget[]傳遞。 TypeType[]應該沒問題 - 它不是「矯枉過正」 - 它是描述類型的適當和預期的方式。此外,還可以通過只是容易實例:

IWidget newInstance = (IWidget)Activator.CreateInstance(someConcreteWidgetType); 
+0

使用'Type'時,我應該使用'GetMember()'來獲得'Image'? –

+0

@BartFriederichs no; 「靜態圖像」的東西是一個壞主意。在這種情況下,Mihai答案中的工廠場景更有意義。 –

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); 
} 
+0

是的,但是這會實例化這個類。這是我想避免的。 –

+0

我的不好 - 我只注意到'getImage'是這個類的靜態方法。 – Mihai

1

使用類型是罰款,馬克說,你可以使用激活創建對象(當你把它在小組中)。如果你想只使用靜態方法來這裏填充工具箱,所以沒有類的創建,然後使用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); 
} 

外面這個答案的範圍都是關於使用反射和大約不得不考慮因素使用一個字符串來傳遞方法名稱,這是脆弱的,重構時沒有幫助...請記住這一點。