【问题标题】:Why does Queryable.OrderBy method allow a dynamic second parameter? [duplicate]为什么 Queryable.OrderBy 方法允许动态第二个参数? [复制]
【发布时间】: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 将所有绑定推迟到运行时,所以它会通过编译器并在运行时绑定。幸运的是,您传入的值与方法将接受的值匹配,因此它在运行时被正确绑定。

标签: c# linq


【解决方案1】:

这里的第二个参数属于接受键选择器的重载。编译器会丢弃该信息。

OrderByIQueryable&lt;T&gt; 的扩展,编译器无法安全地获取运行时的类型信息。

【讨论】:

    猜你喜欢
    • 2023-03-07
    • 2018-05-09
    • 1970-01-01
    • 2013-09-15
    • 2021-03-24
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多