Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design pattern: Polymorphism for list of objects

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?

like image 600
zs2020 Avatar asked Apr 28 '10 03:04

zs2020


1 Answers

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>());
like image 190
Bevan Avatar answered Oct 12 '22 02:10

Bevan