【问题标题】:Is it possible to use Linq and lambdas without including a System.Linq namespace?是否可以在不包含 System.Linq 命名空间的情况下使用 Linq 和 lambda?
【发布时间】:2013-09-11 14:39:27
【问题描述】:

前段时间,我一直在从事一个非常扭曲的项目 - 我只能在单一范围内编写代码,然后将其放入 C# 函数中(由另一个模块)。

我只能使用之前声明的命名空间(我对它们没有影响),并且只能使用我工作范围内的变量。 因此,我无法更改标题和包含的库。

当我想对泛型集合进行操作时,问题就出现了——我既不能使用 lambda 表达式,也不能使用 LINQ——我根本就没有 可以放 using System.Linq; ,因为我无法访问文件头。

我只需要做一件简单的事情,而且不用 LINQ 或 lambda 也很容易管理。然而,在那之后我想知道会发生什么,如果我不得不使用一些 IEnumerable 上更复杂的操作。 由此,我的问题出现了:

是否可以在不更改文件头和添加新命名空间的情况下使用 LINQ 或 lambda?

假设我们有一个List<int> _Numbers = new List<int>();。让它充满一些数字。 现在我想从中选择所有偶数。

在标题中加上using System.Linq;,解决方法很明显:

List<int> _NewList = _Numbers.Where(n => n % 2 == 0).ToList();

List<int> _NewList = (from _Number in _Numbers where _Number % 2 == 0 select _Number).ToList();

但是如果不包含 LINQ,我该如何实现呢? 我的第一个猜测是:

List<int> _NewList = System.Linq. // ??? What to add here?

我知道这个问题相当奇特,走这条路很不寻常,但我只是好奇,我没有找到关于这个案例的信息。

【问题讨论】:

  • System.Linq.Enumerable.Where(_NewList, n =&gt; n % 2 == 0)
  • @nsinreal - 谢谢,这正是我想要的。将其添加为答案,我会将其标记为正确;)
  • 您还可以在类的命名空间声明中包含“使用”语句。这仍然超出您可以访问的范围吗?
  • @JeppeStigNielsen,不,在Queryable 类中。有区别,Enumerable 类方法接受Funcs(编译后的代码),Queryable 类方法接受Expression&lt;Func&lt;..&gt;&gt;(代码存储为抽象语法树,可以重写/处理/等)
  • @nsinreal 是的,我知道,这就是我编写 Linq-to-Objects 的原因。当您查询的“源”只是托管内存中的List&lt;&gt; 时,您可以使用委托和Enumerable 方法。当然,如果您查询诸如 SQL 数据库之类的东西,您会将 lambdas 保存为表达式树,并让一些神奇的“机器”将表达式转换为数据库服务器能够理解的真正 SQL。然后使用Queryable静态类中的方法。

标签: c# linq lambda


【解决方案1】:

没有using 指令,.Where.Select 等方法将无法解析。这意味着 LINQ 语言部分 将不起作用。您将不得不对其进行长期编码(并且向后编码!):

List<int> _NewList = System.Linq.Enumerable.ToList(
    System.Linq.Enumerable.Where(_Numbers, _Number => _Number % 2 == 0)
);

请注意,对于包含组、订单、“让”、连接等的较长示例,这会变得越来越复杂。除非您做的事情相当简单,否则最好找到一种方法来添加 using 指令。

但是请注意,如果 _NumbersList&lt;T&gt;,您可以只使用(对于这个单个示例):

List<int> _NewList = _Numbers.FindAll(_Number => _Number % 2 == 0);

【讨论】:

  • 谢谢,它解释了很多。我知道 FindAll(),但据我所知,它只适用于 List,我正在寻找更通用的方式。
【解决方案2】:

你可以写这样的代码:

System.Linq.Enumerable.Where(_NewList, n => n % 2 == 0)

但是,请注意:如果您的类实现了接口IQueryable&lt;T&gt;,则上面的代码可以完成工作,但速度会更慢。

System.Linq.Queryable.Where(_NewList, n => n % 2 == 0)

因为IQueryable 是用其他 DSL 语言(如 SQL)生成 C# 的方式。使用其他where 条件,您的 SQL 服务器可以尽可能快地选择所需的元素。但是,如果您使用IEnumerableSystem.Linq.Enumerable 在服务器端没有优化,您将获得完整的项目列表,它们将全部加载到内存并在内存中过滤。

【讨论】:

    【解决方案3】:

    不是很清楚为什么你不能访问文件“头”,但是如果你不能在文件开头输入using dirrective,你可以仍然使用完整的限定名类型,如:

    System.Linq.Enumerable(...)
    

    要完成这项工作,您自然还需要包含正确的引用。

    如果这不是您的要求,请澄清。

    【讨论】:

    • 我无法访问文件头,这是我使用的 APi 的问题。我知道我可以添加 System.Linq。在范围内,但我不知道如何进一步评估它。
    猜你喜欢
    • 1970-01-01
    • 2011-02-06
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    • 2021-11-19
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多