How to return IQueryable <Something> as IQueryable <ISomething>
I have a Something class that implements ISomething . How to convert / distinguish from IQueryable<Something> to IQueryable<ISomething> . When I try to execute a throw, I can compile, but the result of the cast is always NULL.
Reference Information. The reason I'm doing this is because my Something class is a CodeSmith generated class (PLINQO template) that has table decorations, methods, etc. My ISomething interface is โPOCO style,โ in that it is dumb and simply reflects the properties of the Something class. It also exists in its own namespace. I do this, so I donโt need to reference the assembly that contains the Something class from my service level. Now the assembly containing the Something class will only need to be referenced at my repository level.
To understand what is happening here, it is important to look at it from the point of view of the type system. For the type system, Something and ISomething are two types that have a relationship similar to inheritance (the implementation is not exactly inheritance, but is closed). The generic types IQueryable<Something> and IQueryable<ISomething> do not have this relationship. These are two completely different types and belong to a completely different part of the inheritance tree (a branch that includes IQueryable) than something or something.
So, when casting from IQuerable<Something> to IQueryable<ISomething> , as for the type system, you can also try casting from IQueryable<double> to IQueryable<IDataRecord> . The result is the same: he does not know how to do this conversion, and therefore the as operator returns null.
C # 4.0 implements one solution to this problem (and not the problem itself, as indicated by others), called covariance ..Net Type Variance allows the type system to have a limited understanding of specialization relationships between two different types that specialize in the same generic type, so when moving from one to another, the type may change (pay attention to the root of the word here).
For code up to .Net 4, you should use something like the .Cast<T>() extension method. But this is not so ideal because it forces a real casting operation where the type variance allows the framework to use an actual type that already exists.