Могу ли я иметь нетипизированную коллекцию в C # - PullRequest
9 голосов
/ 12 августа 2010

Я портирую некоторый код Java на C # и наткнулся на это:

List<?>

Насколько я понимаю, это List типа Unknown.В результате я могу диктовать тип в другом месте (во время выполнения? Я не уверен).

Что является фундаментальным эквивалентом в C #?

Ответы [ 6 ]

6 голосов
/ 12 августа 2010

Я думаю, что лучшим соответствием Java List<?> будет C # 4.0 IEnumerable<out T> Если у вас есть метод, который принимает List<?>, вы можете вызвать его с помощью List<Object> и List<String>, например, так:

List<Object> objList = new List<Object>();
List<String> strList = new List<String>();

doSomething(objList); //OK
doSomething(strList); //OK

public void doSomething(List<?> theList) {
 ///Iterate through list
}

C # 4.0 IEnumerable<T> интерфейс на самом деле IEnumerable<out T>, что означает, что если, скажем, R происходит от T, IEnumerable<T> может быть назначено от IEnumerable<R>.

Итак, все, что вам нужно сделать, это превратить ваш doSomething в DoSomething и принять параметр IEnumerable<T>:

List<Object> objList = new List<Object>();
List<String> strList = new List<String>();

DoSomething(objList); //OK
DoSomething(strList); //OK

public void DoSomething<T>(IEnumerable<T> theList) {
 ///Iterate through list
}

РЕДАКТИРОВАТЬ: Если C # 4.0 недоступен,вы всегда можете вернуться к нетипизированному IEnumerable или IList.

5 голосов
/ 12 августа 2010

Если вам нужен список, который может содержать что угодно, вы можете использовать List<object> или ArrayList.

Если вы хотите список строго типизированного типа, который содержит неизвестный тип, вы должны сделатьуниверсальный класс или метод и используйте List<T>.

Для получения более конкретного совета, пожалуйста, предоставьте более подробную информацию.

3 голосов
/ 12 августа 2010

Во-первых, как упоминалось в другом месте, параметризованный тип неограниченного подстановочного знака отличается от Object . Обобщения не ковариантны. Таким образом, в примере Java OP List<?> отличается от List<Object>. Как пример,

// Unbounded wildcard type is not the same as Object...
List<?> unboundedList = new ArrayList<Object>(); 
List<Object> objectList = new ArrayList<Object>();
unboundedList = objectList;    // no problems
objectList = unboundedList;    // whoops! compile time error

Единственный реальный вариант использования List<?> в Java - это взаимодействие с устаревшими неуниверсальными коллекциями. Это позволяет избежать непроверенных преобразований предупреждений от компилятора.

C # не имеет этого варианта использования. Обобщения C # не были реализованы с использованием стирания. Обратной совместимости между общими и неуниверсальными коллекциями в .net нет - они сосуществуют в основных библиотеках .net. Это отличается от Java, где универсальная версия api наборов заменила неуниверсальную версию в JDK 1.5.

Так что я не думаю, что есть причина хотеть эту конструкцию в C # , и нет прямого эквивалента, который ведет себя так же.

1 голос
/ 12 августа 2010

Звучит так, будто IList - это то, что вы ищете. Это общий интерфейс для списков, что означает, что вам придется разыгрывать все, что выходит, и быть осторожным с тем, что вы вкладываете.

0 голосов
/ 12 августа 2010

Я думаю, что спрашивающий хочет преобразовать что-то вроде этого

int size2(List<?> list)
{
    return 2*list.size(); 
}

List<Foo> list = ...
size2(list);

в эквивалент C #.

Следующий код не будет работать, потому что он принимает только List<Object>, а не List<Foo>

int size2(List<Object> list)
{
    return 2*list.size(); 
}
0 голосов
/ 12 августа 2010

Вы можете просто использовать

List<object>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...