【问题标题】:Does a code that combines single() with yield make any sense?将 single() 与 yield 结合的代码是否有意义?
【发布时间】:2013-05-15 19:47:03
【问题描述】:

我遇到了一个代码,它应该返回列表中预期的单个对象,这个代码有一个迭代器块,它产生找到的项目,我在下面的例子中简化了这个例子:

private static void Methode_A()
{
    Console.Write("{0} ", NumberList(2, 8).Single());     
}

private static IEnumerable<int> NumberList(int min, int max)
{
    while (min < max)
        yield return min++;        
}

Single()yield 结合起来是否有意义或有任何已知的好处,而不是仅仅构建列表并断言它包含一个元素?

【问题讨论】:

  • “虽然我预计代码会在第一个异常(在第二个找到的项目上)后中断,但它会继续运行并在第一个异常之后为所有找到的项目抛出异常。为什么会这样?”抛出第一个异常后,您如何将执行返回到Single()
  • 我认为您的意思是使用First(),它会产生一个或多个项中的第一个。 Single() 产生第一个项目,但如果有多个项目则抛出异常。您向我们展示的代码在出现异常后无法“继续运行”。
  • @MatthewWatson 我没有写代码,我在重构类时发现它,它使用的是 Single,猜想有人想省去对项目计数的检查。
  • “继续运行”是什么意思?您向我们展示的代码无法做到这一点!忽略异常并重试的异常处理程序在哪里? ;)
  • @MatthewWatson 以例外的方式忘记它,这是我对调试器行为的错误解释。我编辑了这个问题。

标签: c# performance linq refactoring yield


【解决方案1】:

它的工作方式如下:

  1. 您拨打NumberList(2, 8).Single()
  2. 执行流程第一次进入while循环,返回第一个结果(2)。
  3. 执行流程在循环的第二次迭代中继续,并返回第二个元素 (3)
  4. .Single 方法立即抛出异常并停止执行,因为它预计枚举器中只包含一个元素

另一方面,如果您致电 NumberList(2, 8).First(),将会发生以下情况:

  1. 执行流程第一次进入while循环,返回第一个结果(2)。
  2. while 循环中的执行流程不再继续,因为已经返回了一个元素并且该元素将是调用的结果

【讨论】:

  • 是的,我敢打赌他打算使用First()
  • 我认为你们都误读了 OP... 或者我误读了。他似乎明确表示他没有得到上述Single() 的行为,他在问为什么。
  • @roliu,除了我的回答中解释的行为之外,get 无法从此代码 sn-p 中获得其他信息。如果他这样做了,那么这不是他真正的代码。
  • @roliu 看看 OP 的代码。它一定会抛出异常。之后它不能“继续运行”——这不会发生。
  • 我不知道。这将取决于您要达到的目标。 .Single 方法在您对某个通过某些唯一代码过滤的集合调用它时很有用,并且您知道最多只能有一个元素(0 或 1 个元素)。例如collection.Single(x =&gt; x.Id == 5)。另一方面,当您只想检索第一个元素时,使用 .First 扩展方法。 NumberList 方法似乎是非常有效的实现。只是有一个你可能不知道的Enumerable.Range(start, count)方法,重新发明了轮子。
猜你喜欢
  • 2012-03-12
  • 1970-01-01
  • 2018-07-21
  • 2014-04-17
  • 2018-02-27
  • 2017-06-25
  • 1970-01-01
  • 2012-08-17
  • 2017-06-12
相关资源
最近更新 更多