These two methods appear to behave the same to me
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.
Are there any reasons to use one over the other? Is one easier to read than the other? Is there a behavior difference that would matter to a caller?
In a normal (non-iterating) method you would use the return keyword. But you can't use return in an iterator, you have to use yield break . In other words, yield break for an iterator is the same as return for a standard method. Whereas, the break statement just terminates the closest loop.
It specifies that an iterator has come to an end. You can think of yield break as a return statement which does not return a value. For example, if you define a function as an iterator, the body of the function may look like this: for (int i = 0; i < 5; i++) { yield return i; } Console.
Empty<T> actually returns an empty array of T (T[0]), with the advantage that the same empty array is reused. Note that this approach is not ideal for non-empty arrays, because the elements can be modified (however an array can't be resized, resizing involves creating a new instance).
"yield break" breaks the Coroutine (it's similar as "return"). "yield return null" means that Unity will wait the next frame to finish the current scope. "yield return new" is similar to "yield return null" but this is used to call another coroutine.
If you intend to always return an empty enumerable then using the Enumerable.Empty<string>()
syntax is more declarative IMHO.
The performance difference here is almost certainly not significant. I would focus on readability over performance here until a profiler showed you it was a problem.
IEnumerable<T>
methods with yield break
or yield return
in their bodies gets transformed to state machines. In this kind of methods you can't mix yield returns with traditional returns. What I mean is that if you yield something in some part of the method, you can't return a ICollection in another.
In the other hand, suppose you're implementing a method with return type IEnumerable<T>
by adding items to a collection, and then returning a readonly copy of the collection. If by some reason you want to just return an empty collection you can't do a yield break
. All you can do is just return Enumerable.Empty<T>()
.
If you've profiled both ways, and there's no significant change, then you can just forget about it :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With