difference between List<object> and List<MyClass>

  • Thread starter Stephan Steiner
  • Start date
S

Stephan Steiner

Hi

I seem to have a bit of trouble understanding one bit of how generics work:

In C#, every class automatically derives from object, and inherits a bunch
of properties (i.e. ToString()). Thus,

(MyClass is object) should always evaluate as true.

However, if I have a method with the following signature:

private void myMethod(List<object> input)

And I try to call it

myMethod(new List<MyClass>())

the compiler complains that it cannot convert from
System.Collections.Generic.List<MyNamespace.MyClass> to
System.Collections.Generic.List<object>. And if I try to cast List<MyClass>
to List<object> that doesn't work either.

Likewise

List<object> myObjs = new List<object>();
myObjs.AddRange(new List<MyClass>());

fails with the same error. However, if I I fill up myObjs as follows:

List<object> myObjs = new List<object>();
List<MyClass> myClasses = new List<MyClass>();
foreach (MyClass c in myClasses)
{
myObjs.Add((object)c);
}

then it works. Even if I leave away the cast to object in the line
myObjs.Add(..) it works (as is to be expected since MyClass is an object.

Since ever class derives from object, why do the the first two examples not
work? Does class inheritance not translate into generics inheritance?

Regards
Stephan
 
J

Jon Skeet [C# MVP]

Since ever class derives from object, why do the the first two examples not
work? Does class inheritance not translate into generics inheritance?

Generics aren't covariant by type parameter - so as you say, List<Foo>
doesn't derive from List<Bar> just because Foo derives from Bar.

In the general case, this is a good thing which improves type safety.
Suppose it worked as you expected it to. In that case, this code would
compile, but have to fail at run time:

List<string> strings = new List<string>();
List<object> objects = strings;
objects.Add(new object());

Now, in the case of APIs which only ever *return* values of their type
parameter, it would be okay - and contravariance would be acceptable
for APIs which only ever receive values of their type parameter as
method parameters. That's available in the CLR for interfaces, but C#
doesn't expose it.

Hope that helps. Here's a lot more on it:

http://blogs.msdn.com/rmbyers/archive/2005/02/16/375079.aspx
http://blogs.msdn.com/rmbyers/archive/2006/06/01/613690.aspx

Jon
 
J

Jon Skeet [C# MVP]

(orhttp://tinyurl.com/3awpp7)

;-p

Indeed. Note how my example was exactly the same too - though retyped!

I really must get round to writing an article about it some time -
it's probably the most frequently asked question about generics.

Jon
 
S

Stephan Steiner


Not it hasn't.. I'm sorry about the repost.. for some wicked reason,
neither the original message nor this one ever showed up in OE (ever
other message I post does show up) - so I figured for some reason they
had been discarded.. only when I used google groups to search for my
messages did I find both - plus all the answers.

Thanks to Jon for the explanation and links on the topic - they're
very helpful.

Regards
Stephan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top