gpt4 book ai didi

c# - Nerd Dinner 教程中 C# yield 关键字的有趣用法

转载 作者:可可西里 更新时间:2023-11-01 08:04:37 35 4
gpt4 key购买 nike

在完成教程(专业 ASP.NET MVC - Nerd 晚餐)时,我遇到了这段代码:

public IEnumerable<RuleViolation> GetRuleViolations() {
if (String.IsNullOrEmpty(Title))
yield return new RuleViolation("Title required", "Title");
if (String.IsNullOrEmpty(Description))
yield return new RuleViolation("Description required","Description");
if (String.IsNullOrEmpty(HostedBy))
yield return new RuleViolation("HostedBy required", "HostedBy");
if (String.IsNullOrEmpty(Address))
yield return new RuleViolation("Address required", "Address");
if (String.IsNullOrEmpty(Country))
yield return new RuleViolation("Country required", "Country");
if (String.IsNullOrEmpty(ContactPhone))
yield return new RuleViolation("Phone# required", "ContactPhone");
if (!PhoneValidator.IsValidNumber(ContactPhone, Country))
yield return new RuleViolation("Phone# does not match country", "ContactPhone");
yield break;
}

我已经阅读了 yield ,但我想我的理解还是有点模糊。它似乎要做的是创建一个对象,该对象允许循环遍历集合中的项目而不实际执行循环,除非绝对必要。

不过,这个例子对我来说有点奇怪。我认为它正在做的是延迟创建任何 RuleViolation实例,直到程序员使用 for each 实际请求集合中的特定项目或 LINQ 扩展方法,如 .ElementAt(2) .

除此之外,我还有一些问题:

  1. 何时执行 if 的条件部分语句得到评估?当GetRuleViolations()被调用或可枚举实际迭代时?换句话说,如果 Title 的值从 null 更改至 Really Geeky Dinner在我调用 GetRuleViolations() 的时间之间当我尝试实际迭代它时,将 RuleViolation("Title required", "Title")创建还是不创建?

  2. 为什么是yield break;必要的?它到底在这里做什么?

  3. 假设 Title为 null 或空。如果我调用 GetRuleViolations()然后连续两次迭代结果枚举,new RuleViolation("Title required", "Title") 将迭代多少次被称为?

最佳答案

包含 yield 命令的函数与普通函数的处理方式不同。当调用该函数时,幕后发生的事情是匿名类型由函数的特定 IEnumerable 类型构造,该函数创建该类型的对象并返回它。匿名类包含执行函数主体的逻辑,直到每次调用 IEnumerable.MoveNext 时执行下一个 yield 命令。这有点误导,函数体不像普通函数那样分批执行,而是分块执行,每 block 在枚举器向前移动一步时执行。

关于您的问题:

  1. 正如我所说,当您迭代到下一个元素时,每个 if 都会被执行。
  2. yield break 在上面的例子中确实不是必需的。它的作用是终止枚举。
  3. 每次迭代可枚举对象时,都会强制再次执行代码。在相关行打个断点,自己测试。

关于c# - Nerd Dinner 教程中 C# yield 关键字的有趣用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1971053/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com