« Return to Thread: Array and IEnumerable

Re: Array and IEnumerable

by Michael Hutchinson :: Rate this Message:

Reply to Author | View in Thread

On Wed, Jul 1, 2009 at 1:13 AM, Trouve Antoine<trouve.antoine@...> wrote:

>>> This is incorrect. List<Subclass> cannot be cast to List<Superclass> on
>>> .NET.
>>>
>>> Some examples like this can be solved by generic
>>> covariance/contravariance in .NET 4.0. See
>>> http://themonkeysgrinder.blogspot.com/2009/02/c-4-is-now.html for some
>>> explanations. However, since System.Generic.Collections.List<T> both
>>> accepts and returns objects of type T, I don't believe it could be
>>> made variant.
>>
>> Ho, you're right. I think this behaviour has changed since .NET 2.0.
>> I've just checked and one of my old project do not compile anymore.
>> ... or I might have missed something.
>
> I have missed something and written too fast: this projects works in the
> case I use my old interfaces (e.g. IList instead of List)
> It the point explained in your link as "variance" right ? By the way I
> remember it was not supported by Mono 1.3 or something.
> I tested and it works with gmcs 2.4 (and 1.9 since I've just tested).

What I said is true for "normal" (nonvariant) generic types.

However, arrays aren't really generic types. They are treated
"specially" by the runtime, so that they can be cast to IList<T> /
ICollection<T> / IEnumerable<T>, where T is the array element type or
any supertype. Presumably your problem was a bug in this feature, in
an older version of Mono.

This is demonstrated by the following sample.

using System;
using System.Collections.Generic;

class Program
{
        class A {}
        class B : A {}

        static void Main (string[] args)
        {
                B[] foo = new B[0];
                Console.WriteLine (foo is IList<B>); // true
                Console.WriteLine (foo is IList<A>); // true

                List<B> bar = new List<B> ();
                Console.WriteLine (bar is IList<B>); // true
                Console.WriteLine (bar is IList<A>); // FALSE
        }
}


Covariance and contravariance are interesting because they make this
kind of casting possible for generic types. They're in .NET 4.0, which
is not yet released, and hence are not yet supported by Mono either.
There are plenty of explanations on the web, so I won't got into
details here.

--
Michael Hutchinson
http://mjhutchinson.com
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@...
http://lists.ximian.com/mailman/listinfo/mono-devel-list

 « Return to Thread: Array and IEnumerable