Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ Union different types - dynamically casting to an interface?

I have 10 tables which are presenting to LINQ as different types, but share exactly the same properties. When I try to run a union on them, the compiler tells me that:

"Argument 2: cannot convert from 'System.Collections.IEnumerable' to 'System.Collections.Generic.IEnumerable<LINQPad.User.TelJun2011>'"

The code looks like this

var jul = (from n in TelJul2011s select n);

var jun = (from p in TelJun2011s select p);

jun.Union(jul).Dump();

I've done my research and understand that unions cannot be performed across different types, I also understand that unions can be performed on anonymous types if they share the same properties. This option will not work for me, as I need all the properties from all the tables and don't want to have to type out the same anonymous type 10 times - once for each variable. I want the compiler to infer that they are all the same type based on the fact that all properties are identical.

I've already tried casting to an IEnumberable, Iqueryable, Datatable etc. using both the AsQueryable() type functions, and the "as" keyword. None of that seems to do the trick for me.

I'm wondering if there is some way of doing this by casting dynamically to a parent type. I can't edit the initial declarations of the classes, so can't implement a common interface on them to cast to. But is there some way I can downcast the types into a common interface when they are used, without writing a conversion from each type to a parent interface?

Thanks for any advice!

like image 855
analystic Avatar asked Jun 27 '26 08:06

analystic


1 Answers

The result of the Union will be an IEnumerable<Xxx> but in this case you have to specify what Xxx is. If the types TelJun2011 and TelJul2011 are not structs (value-types), you can utilize the covariance of IEnumerable<out T> like this:

jun.Union<object>(jul)

This works because TelJun2011 and TelJul2011 are both object, and then by covariance IEnumerable<TelJun2011> and IEnumerable<TelJul2011> are both IEnumerable<object>.

Of course object does not possess all the properties common to TelJun2011 and TelJul2011. It would be better if these two types had a more useful common base class or implemened a common interface, because then you could say e.g.:

jun.Union<ITelMonth>(jul)

where ITelMonth were some type containing the common properties you want.

like image 139
Jeppe Stig Nielsen Avatar answered Jun 28 '26 21:06

Jeppe Stig Nielsen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!