2010-04-23 97 views
10

我試圖在通用列表中存儲泛型對象的列表,但我很難聲明它。我的對象看起來像:泛型的通用列表

public class Field<T> 
{ 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public T Value { get; set; } 

    /* 
    ... 
    */ 
} 

我想創建這些列表。我的問題是,在列表中的每個對象都可以有一個單獨的類型,從而使填充的列表可能包含這樣的事情:

{ Field<DateTime>, Field<int>, Field<double>, Field<DateTime> } 

那麼,如何聲明? (我想保持儘可能的類型安全,所以我不想使用ArrayList)。

+0

然而,這是一個有趣的想法,「儘可能保持類型安全」,但是,你不是在違反http://en.wikipedia.org/wiki/YAGNI概念嗎?想想你將如何訪問該列表,你是否真的需要它具體的? – 2010-04-23 20:54:55

回答

21

這情況下它可能益處你有包含非通用比特一個抽象基類(或接口):

public abstract class Field 
{ 
    public string Name { get; set; } 
    public string Description { get; set; } 
} 

public class Field<T> : Field 
{  
    public T Value { get; set; } 

    /* 
    ... 
    */ 
} 

然後就可以有一個List<Field>。這表達了您實際知道的關於該列表的所有信息。您不知道字段值的類型,因爲它們可能因字段而異。

+0

@Jon - 第一類應該是泛型還是簡單類? – Giorgi 2010-04-23 20:42:56

+1

@Giorgi,'抽象類字段'看起來像一個錯字。我冒昧地糾正它。 – 2010-04-23 20:48:58

+0

他仍然需要投入才能獲得實際的值類型......但這只是我能想到的唯一解決方案,沒有實際的「元組」類型。 – tames 2010-04-23 20:50:40

5

也許實現一個接口。

interface IField 
{ 
} 

class Field<T> : IField 
{ 
} 

...

List<IField> fields = new List<IField>() { new Field<int>(), new Field<double>() }; 
+0

這使得他處於相同的位置,因爲IField不包含類型(T)。不同於只使用'object',因爲他仍然必須施展才能獲得價值 – tames 2010-04-23 20:47:17

+0

@tames,他處於更好的位置,因爲他的列表元素必須實現IField(或者繼承Field,在Jon的例子中)。列表仍然比對象列表的類型更強。 – 2010-04-23 20:50:53

+0

@anthony ...我同意,並且我已經使用了界面和基類解決方案。 – tames 2010-04-23 21:01:19

5

你無法不知道在編譯時的泛型類型聲明泛型類型的列表。

可以聲明一個List<Field<int>>List<Field<double>>,但對於Field<int>Field<double>object沒有其他常見的基本類型。所以只有List<T>可以容納不同種類的字段將是List<object>

如果你想要一個更具體的列表類型,你必須使Field<T>類繼承一個類或實現一個接口。然後,您可以將其用於列表中的泛型類型。