考虑下面的代码
public class CommentBll : IBaseBllPersistor<Comment>
{
public List<Comment> GetData<TProp>(Expression<Func<Comment, TProp>> selector)
{
using (var context = new WebsiteContext())
{
var query = (from q in context.Comment
select new CommentDto
{
ExtraProp = q.Name+q.Id.ToString(),
PostDate = q.PostDate,
}).OrderBy(selector);
return query.ToList();
}
}
public class CommentDto: Comment
{
public string ExtraProp { get; set; }
}
}
public class Comment: IBaseModel
{
public string CommentText { get; set; }
public DateTime PostDate { get; set; }
}
当我从查询末尾删除这部分时
OrderBy(selector)
我收到此错误,
Error CS0029 Cannot implicitly convert type System.Collections.Generic.List<CommentDto> to System.Collections.Generic.List<Comment>
我知道协方差,并且我知道错误与它有关,但为什么当我添加 OrderBy(selector)
时错误消失了?
知道为什么会发生这种情况吗?
最佳答案
Any ideas why this might be happening?
这并不难解释。
让您的查询分为两部分:
var queryA = (from q in context.Comment
select new CommentDto
{
ExtraProp = q.Name+q.Id.ToString(),
PostDate = q.PostDate,
});
var query = queryA.OrderBy(selector);
queryA
的类型是 IQueryable<CommentDto>
.
现在,selector
的第一个泛型参数的类型是 Comment
。自 IQueryable<T>
是协变的且 Expression<TDelegate>
是不变的,编译器满足第二个查询的唯一方法是威胁 queryA
如IQueryable<Comment>
,因此类型为 query
是 IOrderedQueryable<Comment>
,最后的ToList
调用产生 List<Comment>
。
显然没有OrderBy
您正在调用ToList
上queryA
结果是List<CommentDto>
。
在后一种情况下,IQueryable<T>
的协方差通过简单地显式指定 ToList
的通用参数,可以轻松获得所需的结果。调用:
return queryA.ToList<Comment>();
关于c# - 协方差和 orderby() 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36374658/