一个泛型列表的通用列表

13

我想把一组通用对象存储在一个通用列表中,但是我在声明它时遇到了困难。我的对象看起来是这样的:

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> }

那么我该如何声明?
List<Field<?>>

我希望尽可能保持类型安全,因此不想使用ArrayList。


“尽可能保持类型安全”是一个有趣的想法,但是,你不觉得这违反了“你不需要它(You Aren't Gonna Need It)”的概念吗?想一想你将如何访问那个列表,你真的需要那么具体吗? - Fábio Batista
3个回答

24

这种情况下,拥有一个包含非泛型部分的抽象基类(或接口)可能会对您有所帮助:

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>,其中包含有关列表的所有实际信息。 您不知道字段值的类型,因为它们可能因字段而异。


@Jon - 第一个类应该是通用的还是简单的类? - Giorgi
1
@Giorgi,“抽象类Field<T>”看起来像是一个打字错误。我已经自作主张进行了更正。 - Anthony Pegram
他仍然需要进行类型转换以获取实际值类型...但这似乎是我能想到的唯一解决方案,没有实际的“元组”类型。 - tames
@tames,他处于更好的位置,因为他列表中的元素必须继承自Field(或在我的示例中实现IField)。该列表仍比对象列表具有更强的类型。 - Anthony Pegram
@anthony... 我同意,我已经使用过接口和基类的解决方案。 - tames

6
你无法在编译时不知道泛型类型的情况下声明泛型类型列表。
你可以声明一个List<Field<int>>或者List<Field<double>>,但除了object之外没有其他公共基类型可用于Field<int>Field<double>。因此,能够容纳不同类型字段的唯一List<T>将是List<object>
如果你想要更具体的列表类型,你需要让Field<T>类继承一个类或实现一个接口。然后,你就可以在列表中使用该类型作为泛型类型。

5

也许需要实现一个接口。

interface IField
{
}

class Field<T> : IField
{
}

...

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

这使他处于同样的位置,因为IField不包含类型(T)。与仅使用“object”没有太大区别,因为他仍然必须进行强制转换才能获取值。 - tames
@tames,他处于更好的位置,因为他列表中的元素必须实现IField(或在Jon的示例中继承自Field)。该列表仍比对象列表更强类型化。 - Anthony Pegram
@anthony... 我同意,我已经使用过接口和基类的解决方案。 - tames

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接