tags:

views:

101

answers:

2

That is the question. What I want to accomplish is something similar to the following Java code:

class A { }
class B extends A { }

public class Tests {
    public static void main(String [] args) {
        ArrayList<? extends A> lists = new ArrayList<B>(); 
    }
}

(in which B extends A means B inherits from A)

Is it possible at all?

Thanks

+6  A: 

No. While C# 4.0 introduces the concept of variance for interfaces, it isn't (and can't be) possible to do what you're asking specifically.

In C# 4.0, you can do this:

IEnumerable<object> foo = new List<int>();


Edit: As Marc points out, this can't be done with value types and reference Types. However, since I think your question was more about a generalized A:B than it was about int:object, I think the point carries. To be accurate, though, what I mean is that C# 4.0 will allow something this:

IEnumerable<object> foo = new List<string>();

But you can't do what you describe. Namely, let's consider:

List<int> foo = new List<int>();
List<object> bar = foo;

bar.Add("baz");

Now, what happens when we try to access foo[0]? You've now broken the type safety on the list.

Adam Robinson
@devoured elysium: In C# 4, generic variance is possible for certain *interfaces* - it is never possible from one generic class to another generic class. So what you could do in C# 4 would be something like: `IEnumerable<A> list = new List<B>();`
LBushkin
The variance doesn't extend between ref-types and value-types. It would work with `IEnumerable<object> foo = List<string>`, but not `int`.
Marc Gravell
@Marc: Thanks for the clarification; I wasn't aware of that caveat. I've edited my answer to reflect that.
Adam Robinson
+3  A: 

Your best bet with List<object> would be to just use the non-generic IList:

IList list = new List<int>();

However! Adding something other than int will cause a runtime exception.

Marc Gravell