考虑以下代码
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)
时错误消失了?
有什么想法可能会发生这种情况吗?
答案 0 :(得分:3)
为什么会发生这种情况的任何想法?
解释起来并不难。
让我们将您的查询分为两部分:
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>
,而不是{{1}的类型} {是query
,最后的IOrderedQueryable<Comment>
调用产生ToList
。
显然没有您List<Comment>
OrderBy
ToList
queryA
,结果为List<CommentDto>
。
在后一种情况下,IQueryable<T>
的协方差可以通过简单明确指定ToList
调用的泛型参数来轻松获得所需结果:
return queryA.ToList<Comment>();
答案 1 :(得分:0)
使用ToList()指定返回类型Comment,如下所述
return query.ToList<Comment>();