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();
}
精彩评论