Вопрос о дженериках в С# по сравнению с Java
В Java я могу указать generic с подстановочным знаком "?". Можно создать такую карту, как этот:
Map<String, ?>
.
Я работаю с С#, и мне нужен Dictionary<String, SomeInterface<?>>
(где? может быть int, double, any type). Возможно ли это в С#?
EDIT:
Пример:
interface ISomeInterface<out T>{
T Method();
void methodII();
}
class ObjectI : ISomeInterface<int>{
...
}
class ObjectII : ISomeInterface<double>{
...
}
class ObjectIII : ISomeInterface<string>{
....
}
Я пытался сопоставить эти объекты в словаре вроде:
Dictionary<String, ISomeInterface<?>> _objs = new Dictionary<String, ISomeInterface<?>();
_objs.Add("Object1", new ObjectI());
_objs.Add("Object2", new ObjectII());
_objs.Add("Object3", new ObjectII());
foreach(var keyVal in _objs){
Console.WriteLine(keyVal.Method());
}
Объекты, которые реализуют ISomeInterface, загружаются во время выполнения с помощью Assembly и Activator.createInstance. В момент создания я не делаю, если объекты реализуют ISomeInterface<int>
или ISomeInterface<double>
.
Любая помощь очень ценится.
Ответы
Ответ 1
Нет.
Однако, если вы используете С# 4, вы можете сделать ISomeInterface
ковариант, чтобы ISomeInterface<Anything>
был конвертирован в ISomeInterface<object>
.
Если ISomeInterface
имеет методы, которые принимают параметры своего типа (в отличие от возвращаемых значений), это будет совершенно невозможно, так как тогда он позволит вам передавать произвольные объекты в качестве параметров.
РЕДАКТИРОВАТЬ. В вашем конкретном случае лучшим решением является сделать IMyInterface<T>
наследование отдельного неродного интерфейса IMyInterface
и переместить все элементы, которые не включают T
, в базовый интерфейс.
Затем вы можете использовать Dictionary<string, IMyInterface>
, и у вас не будет никаких проблем.
Ответ 2
Существует возможность ограничить переменные типа для определенных типов:
public class Map<U, T> where T : IInterface
{
}
Однако вы не можете сделать что-то вроде:
Map<string, T> map = new Map<string, T>()
Ответ 3
Для использования, которое вы описываете, вы можете использовать обходной путь с IDictionary<string, ISomeInterface>
:
interface ISomeInterface
{
object Method();
void Method2();
}
interface ISomeInterface<T> : ISomeInterface
{
T Method();
}
class C1 : ISomeInterface<int>
{
object ISomeInterface.Method() { return Method(); }
public int Method() { return 10; }
public void Method2() { }
}