How to return an IQueryable<Something> as an IQueryable<ISomething>

一笑奈何 提交于 2019-12-07 08:42:26

问题


I have a class Something that implements ISomething. How can I convert/cast from an IQueryable<Something> to an IQueryable<ISomething>. When I try to cast, I am able to compile, but the result of the cast is always NULL.

Background: The reason I am doing this is because my Something class is a CodeSmith-generated class (PLINQO template) that has table mapping decoration, methods, etc. My ISomething interface is "POCO-style", in that it is dumb and simply mirrors the properties of the Something class. It also exists in it's own namespace. I am doing this so I don't have to reference the assembly that holds the Something class from my service layer. The assembly that holds the Something class will only need to be referenced in my repository layer now.


回答1:


You can use LINQ method Cast

 IQueryable<Something> something = ...
 IQueryable<ISomething> casted = something.Cast<ISomething>();



回答2:


To understand what's going on here, it's important to look at this from the perspective of the type system. To the type system, Something and ISomething are two types that have an inheritence-like relationship (implementation is not exactly inheritance, but close). The generic types IQueryable<Something> and IQueryable<ISomething> do not have this relationship. They are two completely different types, and belong to a completely different part of the inheritance tree (the branch that includes IQueryable) than either Something or ISomething.

So when casting from IQuerable<Something> to IQueryable<ISomething>, as far as the type system is concerned you might as well try to cast from IQueryable<double> to IQueryable<IDataRecord>. The result is the same: it doesn't know how to make that conversion, and so the as operator returns null.

One solution to this problem (not the problem itself, as indicated by others) called covariance is implemented in C# 4.0. .Net Type Variance allows the type system to have a limited understanding of the specialization relationship between two different types that specialize the same generic type, so that when casting from one to the other the type can vary (note the root word here).

For code prior to .Net 4, you have to use something like the .Cast<T>() extension method. But this is less ideal, because it forces a real cast operation, where type variance lets the framework use the actual type that's already there.




回答3:


There is an excellent explanation of the Covariance problem you are encountering in the answer to this question.




回答4:


Not how -- but rather, why:

Generic Covariance -- this link will help explain:

C# Generic Covariance



来源:https://stackoverflow.com/questions/2586705/how-to-return-an-iqueryablesomething-as-an-iqueryableisomething

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!