tags:

views:

144

answers:

3

I am aware of http://stackoverflow.com/questions/1174328/passing-a-generic-collection-of-objects-to-a-method-that-requires-a-collection-of

How do I do it in .Net 2.0 where I don't have .Cast ???

It has to be reference equality i.e. copies of the list won't do.

To re-iterate - I cannot return a new list - it has to be the same list

A: 

You want:

List<T>.ConvertAll()

See here for more info.

Winston Smith
This does not meet the stated requirement that the list have reference equality.
Eric Lippert
+8  A: 

You don't.

In C# 2 and 3 it is impossible to have reference equality AND vary the element type.

In C# 4, you can have reference equality and vary the element type; such a conversion is called a "covariant" conversion. Covariant conversions will only be legal on IEnumerable<T>, not on IList<T> or List<T>. Covariant conversions will only be legal when the source and target T types are reference types. In short:

List<Mammal> myMammals = whatever;
List<Animal> x0 = myMammals; // never legal
IEnumerable<Mammal> x1 = myMammals; // legal in C# 2, 3, 4
IEnumerable<Animal> x2 = myMammals; // legal in C# 4, not in C# 2 or 3
IEnumerable<Giraffe> x3 = myMammals; // never legal
IList<Mammal> x4 = myMammals; // legal in C# 2, 3, 4
IList<Animal> x5 = myMammals; // never legal
IList<Giraffe> x6 = myMammals; // never legal
List<int> myInts = whatever;
IEnumerable<int> x7 = myInts; // legal
IEnumerable<object> x8 = myInts; // never legal; int is not a reference type
Eric Lippert
+1  A: 

Eric is right on. His should be the accepted answer. I will add one more suggestion though. If it's your collection (as in you can modify the collection class) you can implement IEnumerable(Of WhateverBase) even if your collection derives from Collection(Of Whatever).

In fact, you could implement IList(Of WhateverBase), ICollection(Of WhateverBase) etc too - and throw runtime exceptions if you get an incompatible type in your Add method for example.

class GiraffeCollection : Collection<Giraffe>, IEnumerable<Animal> {

    IEnumerator<Animal> IEnumerable<Animal>.GetEnumerator() {
        foreach (Giraffe item in this) {
            yield return item;
        }
    }

}
Josh Einstein
Indeed, we fairly often see this pattern used in order to get around the lack of interface covariance. Fortunately it should start disappearing once we have real interface covariance in the languages and base class libraries.
Eric Lippert