Добавление общего объекта в общий список в С#
У меня есть класс, где соответствующая часть выглядит как
class C {
void Method<T>(SomeClass<T> obj) {
list.Add(obj);
}
List<?> list = new List<?>();
}
Как мне определить список, чтобы компилировать класс?
Мне нужен список типов List<SomeClass<?>>
, то есть список объектов SomeClass
, где каждый объект может иметь любой параметр типа. Конструкция Java ?
позволяет это; что такое эквивалент С#? Если такой вещи нет, есть ли подходящее решение? (A List<object>
будет делать, но ужасно уродливо.)
Ответы
Ответ 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<?>();
}
Если ваш общий список является членом, то разумно, что класс должен быть построен с учетом этого. Нам сложно предложить лучший шаблон без использования контекста использования для класса.