Могу ли я иметь Нетипизированную коллекцию в C#

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

List<?>

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

что такое фундаментальный эквивалент в C#?

6 ответов


я думаю, что лучший матч для 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 и признать


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

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

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


во-первых, как уже упоминалось в другом месте,неограниченный подстановочный знак параметризованный тип не совпадает с 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# generics не были реализованы с использованием стирания. Нет обратной совместимости между общими и неродовыми коллекциями в .net - они сосуществуют в основных библиотеках .net. Это отличается от Java, где общая версия api коллекций заменила не общую версию в JDK 1.5.

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


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


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

List<object>


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

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(); 
}