Вопрос о дженериках в C # по сравнению с Java - PullRequest
10 голосов
/ 12 мая 2011

В Java я могу указать универсальный с подстановочным знаком "?".Можно создать карту, подобную этой:

Map<String, ?>.

Я работаю с C # и мне нужно Dictionary<String, SomeInterface<?>> (где? Может быть int, double, anyтип).Возможно ли это в C #?

РЕДАКТИРОВАТЬ:

Пример:

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

Любая помощь очень ценится.

Ответы [ 3 ]

8 голосов
/ 12 мая 2011

номер

Однако, если вы используете C # 4, вы можете сделать ISomeInterface ковариантным , чтобы ISomeInterface<Anything> был преобразован в ISomeInterface<object>.

Если у ISomeInterface есть методы, которые принимают параметры своего параметра типа (в отличие от возвращаемых значений), это будет совершенно невозможно, поскольку тогда это позволит вам передавать произвольные объекты в качестве параметров.

РЕДАКТИРОВАТЬ : В вашем конкретном случае наилучшее решение состоит в том, чтобы IMyInterface<T> наследовал отдельный неуниверсальный интерфейс IMyInterface и перемещал всех членов, которые не включают T, в базу интерфейс.
Затем вы можете использовать Dictionary<string, IMyInterface>, и у вас не будет никаких проблем.

2 голосов
/ 12 мая 2011

Для использования, которое вы описываете, вы можете использовать обходной путь, с 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() { }
}
2 голосов
/ 12 мая 2011

Существует возможность ограничить переменные вашего типа определенными типами:

public class Map<U, T> where T : IInterface
{
}

Однако вы не можете сделать что-то вроде:

Map<string, T> map = new Map<string, T>()
...