Is there any way to optionally return a null with a "return yield" driven iterator?
I would like to return a null in some cases and I don't think this is particular to IEnumerable of type string. Same goes for IEnumerable of type int etc. Thanks
static void Main(string[] args) { var Items = GetItems(); if (Items != null) { foreach (var item in Items) { Console.WriteLine(item); } } else { Console.WriteLine("<null>"); } } static IEnumerable<string> GetItems() { if (false) { yield return "Andy"; yield return "Jennifer"; } return null; // <- Compiler Error: // Cannot return a value from an iterator. // Use the yield return statement to return a value, // or yield break to end the iteration. }
You use "yield return null;" when you want to skip a frame within that test. It just means, run the code below "yield return null;" next frame (not right now). For example, I want to do two tests. Check if a gameobject has Rigidbody component. Check if a gameobject is properly moving (ie: falling down)
"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.
A started coroutines gets added to a list for tge given MonoBehaviour, when the conpiler runs them, if it hits a yield return null, it stops with the coroutine and sets it back in the list. The current frame is run through and next frame starts.
The yield return statement returns one element at a time. The return type of yield keyword is either IEnumerable or IEnumerator . The yield break statement is used to end the iteration. We can consume the iterator method that contains a yield return statement either by using foreach loop or LINQ query.
If you need to things like that (or throw things like ArgumentException
immediately), you need to separate your iterator into two methods:
public IEnumerable<string> GetItems() { if (something) return null; return GetItemsInternal(); } private IEnumerable<string> GetItemsInternal() { // the actual iterator with "yield return" goes here. }
You're not using an enumerable as it was intended (to iterate objects in a collection). If you want to keep your code similar to what it is now, you should do something like this:
static void Main(string[] args) { var Items = GetItems(); foreach (var item in Items) //this will not enter the loop because there are no items in the Items collection { Console.WriteLine(item); } //if you still need to know if there were items, check the Count() extension method if(Items.Count() == 0) { Console.WriteLine("0 items returned"); } } static IEnumerable<string> GetItems() { if (false) { yield return "Andy"; yield return "Jennifer"; } yield break; }
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