技术开发 频道

LINQ项目-支持 LINQ 项目的语言功能


  当我们在 foreach 语句中枚举 justStrings 变量时,将获得一个由两个字符串(“Hello”和“World”)组成的序列。

  延迟的查询计算

  观察力敏锐的读者可能会注意到,标准的 Where 操作符是使用 C# 2.0 中引入的 yield 结构实现的。该实现技术常用于返回值序列的所有标准操作符。使用 yield 的一个有趣的优点是,查询实际上是在迭代完毕后计算的(通过使用 foreach 语句,或者手动使用基础的 GetEnumerator 和 MoveNext 方法)。该延迟计算允许将查询保留为基于 IEnumerable 的值,这些值可以计算多次,每次都可能生成不同的值。

  对于许多应用程序而言,这正是所需的行为。对于希望缓存查询计算结果的应用程序而言,提供的两个操作符(ToList 和 ToArray)会强制立即计算查询,并返回包含查询计算结果的 List 或数组。

  要了解延迟查询计算如何工作,请考虑以下程序,该程序对数组运行了一个简单的查询:
// declare a variable containing some strings string[] names = { "Allen", "Arthur", "Bennett" }; // declare a variable that represents a query IEnumerable ayes = names.Where(s => s[0] == 'A'); // evaluate the query foreach (string item in ayes) Console.WriteLine(item); // modify the original information source names[0] = "Bob"; // evaluate the query again, this time no "Allen" foreach (string item in ayes) Console.WriteLine(item);
  每次迭代变量 ayes 时,都会计算查询。要指示所需结果的缓存副本,我们只需在查询中追加一个 ToList 或 ToArray 操作符,如下所示:
// declare a variable containing some strings string[] names = { "Allen", "Arthur", "Bennett" }; // declare a variable that represents the result // of an immediate query evaluation string[] ayes = names.Where(s => s[0] == 'A').ToArray(); // iterate over the cached query results foreach (string item in ayes) Console.WriteLine(item); // modifying the original source has no effect on ayes names[0] = "Bob"; // iterate over result again, which still contains "Allen" foreach (string item in ayes) Console.WriteLine(item);
  ToArray 和 ToList 都可以强制立即执行查询计算,这与返回单个值的标准查询操作符(例如,First、ElementAt、Sum、Average、All 和 Any)一样。

  初始化复合值

  λ 表达式和扩展方法为我们提供了只从值序列筛选成员的查询所需的全部内容。大多数查询表达式还针对这些成员执行投影,将原始序列的成员有效地转换为值和类型可能不同于原先的成员。要支持编写这些转换,LINQ 依赖一个名为对象初始化表达式 的新结构,以创建结构化类型的新实例。在本文其余部分中,我们将假设定义了以下类型:
public class Person { string name; int age; bool canCode; public string Name { get { return name; } set { name = value; } } public int Age { get { return age; } set { age = value; } } public bool CanCode { get { return canCode; } set { canCode = value; } } }
  对象初始化表达式使我们能够根据类型的公共字段和属性轻松地生成值。例如,要创建 Person 类型的新值,我们可以编写以下语句:
Person value = new Person { Name = "Chris Smith", Age = 31, CanCode = false };

  从语义上说,该语句等效于以下语句序列:

Person value = new Person(); value.Name = "Chris Smith"; value.Age = 31; value.CanCode = false;
0
相关文章