Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't "return" and "yield return" be used in the same method?

Tags:

Why can't we use both return and yield return in the same method?

For example, we can have GetIntegers1 and GetIntegers2 below, but not GetIntegers3.

public IEnumerable<int> GetIntegers1() {   return new[] { 4, 5, 6 }; }  public IEnumerable<int> GetIntegers2() {   yield return 1;   yield return 2;   yield return 3; }  public IEnumerable<int> GetIntegers3() {   if ( someCondition )   {     return new[] {4, 5, 6}; // compiler error   }   else   {     yield return 1;     yield return 2;     yield return 3;   } } 
like image 936
Setyo N Avatar asked Mar 09 '12 08:03

Setyo N


People also ask

What should the return type be for a method that uses yield return?

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.

How to yield return IEnumerable?

The yield type of an iterator that returns IEnumerable or IEnumerator is object . If the iterator returns IEnumerable<T> or IEnumerator<T>, there must be an implicit conversion from the type of the expression in the yield return statement to the generic type parameter.

What is a yield return?

Yield is the income returned on an investment, such as the interest received from holding a security. The yield is usually expressed as an annual percentage rate based on the investment's cost, current market value, or face value.

Does yield break return null?

"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.


2 Answers

return is eager. It returns the entire resultset at once. yield return builds an enumerator. Behind the scenes the C# compiler emits the necessary class for the enumerator when you use yield return. The compiler doesn't look for runtime conditions such as if ( someCondition ) when determining whether it should emit the code for an enumerable or have a method that returns a simple array. It detects that in your method you are using both which is not possible as he cannot emit the code for an enumerator and at the same time have the method return a normal array and all this for the same method.

like image 132
Darin Dimitrov Avatar answered Jan 30 '23 00:01

Darin Dimitrov


No you can't do that - an iterator block (something with a yield) cannot use the regular (non-yield) return. Instead, you need to use 2 methods:

public IEnumerable<int> GetIntegers3() {   if ( someCondition )   {     return new[] {4, 5, 6}; // compiler error   }   else   {     return GetIntegers3Deferred();   } } private IEnumerable<int> GetIntegers3Deferred() {     yield return 1;     yield return 2;     yield return 3; } 

or since in this specific case the code for both already exists in the other 2 methods:

public IEnumerable<int> GetIntegers3() {   return ( someCondition ) ? GetIntegers1() : GetIntegers2(); } 
like image 29
Marc Gravell Avatar answered Jan 29 '23 23:01

Marc Gravell