开发者

Can I have a Untyped Collection in C#

I am porting some Java code to C# and I ran across this:

List<?>

As I understand it this is a List of type Unknown. As a result I can dictate th开发者_运维技巧e type elsewhere (at runtime? I'm not sure).

What is the fundamental equivalent in C#?


I think the best match to Java's List<?> would be C# 4.0 IEnumerable<out T> If you have a method that takes List<?> than you can call it with List<Object> and List<String> like so:

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> interface is actually IEnumerable<out T>, which means that if, say, R derives from T, IEnumerable<T> can be assigned to from IEnumerable<R>.

So, all you have to do is make your doSomething into DoSomething and have accept IEnumerable<T> parameter:

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
}

EDIT: If C# 4.0 is not available, you can always fall back to either untyped IEnumerable or IList.


If you want a list that can hold anything, you can use a List<object> or an ArrayList.

If you want a strongly-typed list that holds an unknown type, you should make a generic class or method and use a List<T>.

For more specific advice, please provide more detail.


Firstly, as mentioned elsewhere, the unbounded wildcard parameterized type is not the same as Object. Generics are not covariant. So in the OP's Java example List<?> is not the same as List<Object>. As an example,

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

The only real use case for List<?> in Java is when interacting with legacy non generic collections. It allows you to avoid unchecked conversion warnings from the compiler.

C# does not have this use case. C# generics were not implemented using erasure. There is no backwards compatibility between the generic and non-generic collections in .net - they co-exist in the core .net libraries. That is different from Java where the generic version of the collections api replaced the non generic version at JDK 1.5.

So I don't think there is a reason to want this construct in C#, and there is no direct equivalent that behaves in the same way.


It sounds like IList is what you're looking for. It's a generic interface for lists, meaning you'll have to cast anything that comes out and be careful what you put in.


You could just use

List<object>


I think the questioner wants to convert something like this

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

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

into C# equivalent.

The following code won't work, because it only accept List<Object>, not List<Foo>

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜