c# - Convert IEnumerable<A> to IEnumerable<B> without knowing types at compile time -


i have 2 types: let's call them , b. can converted b using adapter method.

i have collection of a's in list<a> (it collection type supports ienumerable<a>).

i want convert ienumerable<a> ienumerable<b>. know type of each of , b, , have method convert b, method and/or class not templated itself, not have access template type; e.g. t in ienumerable<t>.

i want write convertcollection method, know "from" of type ienumerable<{something}>:

object convertcollection(object from, type fromtype, type totype, converter converter); 

my converter looks this:

delegate object converter(object from); 

my attempt leaves me here:

object convertcollection(object from, type fromtype, type totype, converter converter) {     return ((ienumerable<object>)from).select(converter); } 

which partly works. if call this

convertcollection(new list<a>() { new a() }, typeof(a), typeof(b), atobconverter); 

the returned collection contain collection of bs, collection of type ienumerable<object>, not ienumerable<b>, because don't know how cast ienumerable<{totype}>. (it matters because result needs serialized).

i can attack other end , create correct return type this:

var result = activator.createinstance(typeof(list<>).makegenerictype(totype)); // todo: populate result here return result; 

but problem achieve todo part, need call list<> methods on result, can't cast type of list<> because of co/contravariance rules, though know type supports list<> methods, can't @ them use them populate list; e.g. use add().

is there way without using 'dynamic' , without reflection? know locate , invoke add() method via reflection, seems shouldn't necessary.

.net 4.0 btw

-- clarification

as euphoric correctly speculates, , tried rather badly failed convey above, know types , b @ runtime, not know them @ compile time. hence direct use of generics not option. know collections (both supplied , must returned) implement generic ienumerable<>. fixed , outside control. (i've adjusted title accordingly).

** edit 2: fixed formatting causing <> not display (easy accidentally omit back-ticks!)

using linq select method:

var result = lista.select(a => converter(a)); 

since using .net 4.0, should avoid using object , use generics.


Comments