IQueryable转换

时间:2014-02-07 13:55:25

标签: c# .net lambda expression iqueryable

为什么转换成行'OK',而不是在线'不行'?

var queryable = new int[]{1, 2, 3}.AsQueryable();

var x = (Expression<Func<IQueryable<int>>>)(() => (from c in queryable select c));

var yy = (Expression<Func<IEnumerable<int>>>)x;  // NOT OK (does not compile)
var zz = (Expression<Func<IEnumerable<int>>>)(() => (from c in queryable select c)); // OK

更新:错误消息为:

  

无法转换类型   System.Linq.Expressions.Expression<System.Func<System.Linq.IQueryable<int>>>   至   'System.Linq.Expressions.Expression<System.Func<System.Collections.Generic.IEnumerable<int>>&GT;'

2 个答案:

答案 0 :(得分:3)

因为Expression是一个类,IEnumerable是一个接口。并且接口和委托的类不是协变的。

这意味着即使B是A的基类,也无法将Expression<A>转换为Expression<B>

所以如果这一行:

() => (from c in queryable select c)

返回

Func<IQueryable<int>>

它可以转换为

Func<IEnumerable<int>>

但如果您已经

Expression<Func<IQueryable<int>>>

无法转换为

Expression<Func<IEnumerable<int>>>

答案 1 :(得分:1)

Expression<T>是一个类,因此不是协变的。

您可以执行以下操作:

Func<IQueryable<int>> qf = () => queryable.Select(c => c);
Func<IEnumerable<int>> ef = qf;

但是,由于类在C#中不协变,即使您可以将Expression<T>的实例分配给Expression<U>,也无法将T分配给U; < / p>