Is yield break equivalent to returning Enumerable<T>.Empty from a method returning IEnumerable<T>
这两种方法在我看来是一样的
1 2 3 4 5 6 7 8 9 | public IEnumerable<string> GetNothing() { return Enumerable.Empty<string>(); } public IEnumerable<string> GetLessThanNothing() { yield break; } |
我已经在测试场景中对每一个进行了分析,但在速度上看不到有意义的差异,但是
有没有理由使用一个而另一个?一个比另一个容易阅读吗?打电话的人有没有行为上的差异?
如果您打算总是返回一个空的可枚举的,那么使用
这里的性能差异几乎肯定不显著。在这里,我将关注性能的可读性,直到一个分析器向您显示这是一个问题。
体内含有
另一方面,假设您正在通过向集合中添加项,然后返回集合的只读副本来实现返回类型为
如果你对这两种方式都进行了分析,并且没有显著的变化,那么你可以忘记它:)
I've profiled each in test scenarios and I don't see a meaningful difference in speed, but the yield break version is slightly faster.
我想您的分析测试不包括程序启动速度。
如果在ilspy中打开一个包含测试方法的程序并关闭枚举器反编译,您将发现一个名为
1 2 3 4 5 6 7 8 9 | bool IEnumerator.MoveNext() { int num = this.<>1__state; if (num == 0) { this.<>1__state = -1; } return false; } |
有趣的是,我今天早上读了这篇文章,几个小时后我被这个例子击中了——当你有更多的代码时发现了不同之处:
1 2 3 4 5 6 7 | public static IEnumerable<T> CoalesceEmpty<T>(IEnumerable<T> coll) { if (coll == null) return Enumerable.Empty<T>(); else return coll; } |
您不能将第一个返回更改为yield break,因为您还必须更改第二个返回(更改为更长的版本)。
似乎
不过,我同意另一个贴出的答案。空是做这件事的"首选"方式。