【问题标题】:How Linq infers types from LambdaLinq 如何从 Lambda 推断类型
【发布时间】:2012-08-03 20:38:29
【问题描述】:

这是原始的 Linq:

       var developersUsingCSharp =
                from d in developers
                    where d.Language == "C#"
                    select d.Name;

这可以写成:

     Func<Developer, bool> filteringPredicate = d => d.Language == "C#";
     Func<Developer, string> selectionPredicate = d => d.Name;
     IEnumerable<string> developersUsingCSharp =
                    developers
                         .Where(filteringPredicate)
                         .Select(selectionPredicate);

上面我们已经明确定义了 Func 委托。所以在

     Func<Developer, bool> filteringPredicate = d => d.Language == "C#";

已知d是Developer类型,返回类型是bool。同样,对于

     Func<Developer, string> selectionPredicate = d => d.Name;

已知d是Developer类型,返回类型是string。但是,在以下相同查询的有效形式中,这些类型是如何推断的:

IEnumerable<string> developersUsingCSharp =
                      developers
                         .Where(d => d.Language == "C#")
                         .Select(d => d.Name);

【问题讨论】:

  • 参考您的最后一个代码块,该查询尚未推断。除非你调用像 ToList()、ToArray() 这样的贪婪方法,否则默认情况下它仍然是延迟的。
  • @LeoLuis:他的意思是类型推断而不是获取数据。这些概念不相关。

标签: c# linq delegates lambda extension-methods


【解决方案1】:

编译器知道developers 实现了IEnumerable&lt;Developer&gt;。这意味着developers 之外的任何IEnumerabler&lt;T&gt; 扩展都将具有Developer 类型的项目。

【讨论】:

  • 好的,所以可以推断出 d 的类型,但是返回类型呢?布尔和字符串?
【解决方案2】:

编译器知道developers 中的元素是Developers,因此它可以推断出两个lambda 的第一个类型参数。编译器可以通过检查 lambda 的返回值来推断第二种类型的参数:bool 对应于Wherestring 对应于Select

【讨论】:

  • 所以它在运行时这样做?!?。它可以在运行时“检查”类型吗?当然?那么它的类型安全吗?
  • 不,编译器会这样做。它在编译时完成。它是类型安全的。
  • 它在编译时进行推断。所以它绝对打字安全
  • 谢谢 没有书明确说明,尽管他们解释了代码。
【解决方案3】:

我真的没有看到任何问题;但是,请查看 C# 规范的第 7.5.2 节。我包含描述如何执行匿名和通用方法解析和类型推断的小节。

【讨论】:

    猜你喜欢
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多