views:

148

answers:

5

Suppose I have a class A, and A1, A2 inherits from A. There are 2 functions:

List<A1> getListA1(){...}
List<A2> getListA2(){...}

Now I want to do something similar to both A1 and A2 in another function

public void process(List<A>){...}

If I want to pass the instance of either ListA1 or ListA2, of course the types doesn't match because the compiler doesn't allow the coercion from List< A1> to List< A>. I can't do something like this:

List<A1> listA1 = getListA1();
List<A> newList = (List<A>)listA1; //this is not allowed.

So what is the best approach to the process()? Is there any way to do it in a universal way rather than write the similar code to both List and List?

+5  A: 

Use a wildcard bound:

public void process(List<? extends A>){...}
matt b
This work for Java. Thanks! Just voted.
sza
A: 

Use the Cast extension method from IEnumerable.

Corey Sunwold
A: 

Can't getListA1() and getListA2() just return List types in the first instance?

List<A> getListA1(){...}
List<A> getListA2(){...}
rojoca
I thought about this before. The problem is these 2 methods are used some where else, and I have change all related place.
sza
+5  A: 

While I can't offer a java solution, here are some for C# ...

If you can alter the signature of Process to accept IEnumerable ...

public void Process(IEnumerable<A> myList) { ... }

then, in C# 4.0, everything will just work, thanks to the improved support for co- and contra-variance.

If you're working in C# 3.0, you can introduce a generic type parameter to the method:

public void Process<T>(List<T> myList) where T : A { ... }

Then, you can call passing either List or List and the generic type parameter will bind accordingly. Note that you don't often have to specify it directly, as type inferrence will usually give you what you need.

If this doesn't suit, you could convert the List using the Cast extension method from Enumerable:

public void Process(List<A> myList) { ... }

var someList = getListA1();
Process( someList.Cast<A>());
Bevan
+1  A: 
import java.util.*;

class A {
    int x;
}

class A1 extends A {
    int y;
}

class A2 extends A {
    int z;
}

public class polymorphisimForListOfObjects {
    static void foo(List<? extends A> l) { // probably can't modify the list
        System.out.println(l);
    }

    public static void main(String[] arguments) {
        A1[] a1 = { new A1(), new A1() };
        A2[] a2 = { new A2(), new A2() };
        List<A1> l1 = Arrays.asList(a1);
        List<A2> l2 = Arrays.asList(a2);
        foo(l1);
        foo(l2);
    }

}
Ray Tayek
Thank you! Just gave you a vote.
sza