【发布时间】:2020-01-16 16:49:17
【问题描述】:
寻找问题的解决方案,我找到了以下代码:
public interface IOrderExpression<TEntity>
{
OrderDirection Direction { get; set; }
LambdaExpression Selector { get; }
}
public static IQueryable<T> GetOrder<T>(this IQueryable<T> queryable, IList<IOrderExpression<T>> orderExpressions)
{
var firstOrderExpression = orderExpressions.First();
queryable = firstOrderExpression.Direction == OrderDirection.Ascending
? Queryable.OrderBy(queryable, firstOrderExpression.Selector as dynamic)
: Queryable.OrderByDescending(queryable, firstOrderExpression.Selector as dynamic);
[..]
}
在第一次阅读时,我认为:
这段代码无法编译,
Queryable类中没有匹配动态参数的OrderBy函数。
但是这段代码被标记为答案,所以我在我的 IDE 中编写了它以确保它。我是这样写的:queryable.OrderBy(firstOrderExpression.Selector as dynamic),它没有按预期编译:
“IQueryable”不包含“OrderBy”的定义,最佳扩展方法重载“Queryable.OrderBy”需要“IQueryable”类型的接收器
然后,我完全按照我找到的方式编写了它(使用Queryable.OrderBy([..]),它实际上可以编译(并且在运行时工作!)。这让我更加困扰,因为我认为这两种调用扩展方法的方法是相同的。 ..
谁能解释一下为什么编译器允许这样做?
【问题讨论】:
-
dynamic类型和扩展方法的使用不能混用。 -
副本解释了为什么第一次尝试没有编译。至于为什么第二个这样做,这是因为
dynamic将所有绑定推迟到运行时,所以它会通过编译器并在运行时绑定。幸运的是,您传入的值与方法将接受的值匹配,因此它在运行时被正确绑定。