Подтвердить что ты не робот

Добавление общего объекта в общий список в С#

У меня есть класс, где соответствующая часть выглядит как

class C {
    void Method<T>(SomeClass<T> obj) {
        list.Add(obj);
    }
    List<?> list = new List<?>();
}

Как мне определить список, чтобы компилировать класс?

Мне нужен список типов List<SomeClass<?>>, то есть список объектов SomeClass, где каждый объект может иметь любой параметр типа. Конструкция Java ? позволяет это; что такое эквивалент С#? Если такой вещи нет, есть ли подходящее решение? (A List<object> будет делать, но ужасно уродливо.)

4b9b3361

Ответ 1

Я не думаю, что вы можете сделать это в С#... вам нужно добавить параметр type в класс:

class C<T> {
    void Method(SomeClass<T> obj) {
        list.Add(obj);
    }
    List<SomeClass<T>> list = new List<SomeClass<T>>();
}

Другой вариант - использовать интерфейс:

class C {

    void Method<T>(T obj)
         where T : ISomeClass {
        list.Add(obj);
    }
    List<ISomeClass> list = new List<ISomeClass>();
}

Ответ 2

Чтобы сделать то, что вы хотите, у вас есть два варианта.

Вы можете использовать List <object> , и обрабатывать объекты. Это не будет типичным и будет иметь проблемы с боксом/распаковкой для типов значений, но он будет работать.

Другой вариант - использовать общее ограничение для ограничения базового класса или интерфейса и использовать список <Interface> .

Ответ 3

К сожалению, нет прямого эквивалента в С# 3.0, поскольку дженерики являются инвариантными. Вы сможете сделать что-то вроде этого грациозно, используя С# 4.0 безопасную функцию co/contra-variance. Чтобы обойти это, вы можете наследовать SomeClass<T> из неродной базы и создать вместо нее List<BaseClass>. Если каждый экземпляр класса должен содержать только один тип, вы можете сделать сам класс обобщенным и установить там параметр типа.

Ответ 4

Я ничего не знаю о конструкции Java ?, но я думаю, что следующее наиболее точно сохраняет ваш существующий синтаксис, а также соответствует вашему описанию.

    class SomeClass<T>
    {
    }

    class C
    {
        void Add<T>(SomeClass<T> item)
        {
            Type type = typeof(SomeClass<T>);
            if (!list.ContainsKey(type))
                list[type] = new List<SomeClass<T>>();
            var l = (List<SomeClass<T>>)list[type];
            l.Add(item);
        }

        public void Method<T>(SomeClass<T> obj)
        {
            Add(obj);
        }
        readonly Dictionary<Type, object> list = new Dictionary<Type, object>();
    }

проверьте его следующим образом:

    class Program
    {
        static void Main(string[] args)
        {
            var c = new C();
            var sc1 = new SomeClass<int>();
            var sc2 = new SomeClass<String>();
            c.Method(sc1);
            c.Method(sc2);
            c.Method(sc1);
            c.Method(sc2);
        }
    }

Ответ 5

Лично я сделал бы это, когда это было возможно; переместите общий параметр из метода в класс.

class C<T> {
    void Method(SomeClass<T> obj) {
        list.Add(obj);
    }
    List<?> list = new List<?>();
}

Если ваш общий список является членом, то разумно, что класс должен быть построен с учетом этого. Нам сложно предложить лучший шаблон без использования контекста использования для класса.