通过教程(Professional ASP.NET MVC - Nerd Dinner),我遇到了这段代码:
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)
.
不过,除此之外,我还有一些问题:
if
何时评估语句的条件部分?何时GetRuleViolations()
调用或何时实际迭代可枚举?换句话说,如果在我调用的时间和我尝试实际迭代它的时间之间的值Title
从null
to变化,是否会被创建?Really Geeky Dinner
GetRuleViolations()
RuleViolation("Title required", "Title")
为什么是
yield break;
必要的?它到底在这里做什么?假设
Title
是 null 或空。如果我调用GetRuleViolations()
then 连续两次迭代生成的可枚举,将new RuleViolation("Title required", "Title")
调用多少次?