Общий список дженериков

Я пытаюсь сохранить список общих объектов в общем списке, но мне трудно его объявить. Мой объект выглядит так:

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).

Ответ 1

Это ситуация, когда вам может пригодиться абстрактный базовый класс (или интерфейс), содержащий неэквивалентные биты:

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>. Это выражает всю информацию, которую вы действительно знаете о списке. Вы не знаете типы значений полей, поскольку они могут варьироваться от одного поля к другому.

Ответ 2

Возможно реализовать интерфейс.

interface IField
{
}

class Field<T> : IField
{
}

...

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

Ответ 3

Вы не можете объявить список общих типов, не зная об общем типе во время компиляции.

Вы можете объявить List<Field<int>> или List<Field<double>>, но нет другого общего базового типа для Field<int> и Field<double>, чем object. Таким образом, единственный List<T>, который может содержать разные типы полей, будет List<object>.

Если вам нужен более конкретный тип для списка, вам нужно сделать класс Field<T> наследовать класс или реализовать интерфейс. Затем вы можете использовать это для общего типа в списке.