سؤال

Why is conversion in line 'OK' possible, while not on line 'NOT 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

Update: The error message is:

Cannot convert type System.Linq.Expressions.Expression<System.Func<System.Linq.IQueryable<int>>> to 'System.Linq.Expressions.Expression<System.Func<System.Collections.Generic.IEnumerable<int>>>'

هل كانت مفيدة؟

المحلول

Because Expression is a class and IEnumerable is an interface. And classes are not covariant while interfaces and delegates are.

That means that you can't convert an Expression<A> to Expression<B> even if B is a base class of A.

So if this line:

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

returns

Func<IQueryable<int>>

it can be converted to a

Func<IEnumerable<int>>

but if you already have

Expression<Func<IQueryable<int>>>

it can't be converted into

Expression<Func<IEnumerable<int>>>

نصائح أخرى

Expression<T> is a class and is therefore not covariant.

You can do the following:

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

however, since classes are not covariant in C#, you cannot assign an Expression<T> to an Expression<U> even if you can assign an instance of T to U;

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top