Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What kind of class does yield return return

Tags:

c#

So I've notice that this code works:

class Program
{
    public static void Main()
    {
        Int32[ ]numbers = {1,2,3,4,5};

        using (var enumerator = Data().GetEnumerator())
        {

        }
    }

    public static IEnumerable<String> Data()
    {
        yield return "Something";
    }
}

In particular, I'm curious about the using block, since:

Int32[] numbers = { 1, 2, 3, 4, 5, 6 };

using (var enumerator = numbers.GetEnumerator())
{

}

fails with a compiler error. Obviously, the class that yield return returns is IDisposable while a regular array enumerator is not. So now I'm curious: what exactly does yield return create?

like image 850
sircodesalot Avatar asked Mar 11 '13 15:03

sircodesalot


People also ask

What yield return does?

Yield is the amount an investment earns during a time period, usually reflected as a percentage. Return is how much an investment earns or loses over time, reflected as the difference in the holding's dollar value. The yield is forward-looking and the return is backward-looking.

What does yield return do in C#?

The MSDN states: "When a yield return statement is reached in the iterator method, expression is returned, and the current location in code is retained. Execution is restarted from that location the next time that the iterator function is called."

Does yield return a list?

At first sight, we might think that this is a function which returns a list of 5 numbers. However, because of the yield-statement, this is actually something completely different. This method doesn't in fact return a list at all. What it does is it creates a state-machine with a promise to return 5 numbers.

How do you use yield return?

To use "yield return", you just need to create a method with a return type that is an IEnumerable (arrays and collections in. Net implements IEnumerable interface) with a loop and use "yield return" to return a value to set in the loop body.


1 Answers

IEnumerator<T> implements IDisposable, as you can see in the Object Browser or in MSDN.

The non-generic IEnumerator does not.

The base Array class implements IEnumerable but not IEnumerable<T>. (since Array is not generic)
Concrete array types do implement IEnumerable<T>, but they implement GetEnumerator() explicitly (I'm not sure why).
Therefore, the GetEnumerator() visible on any array type returns IEnumerator.

The generic IEnumerable<T> implementation returns a System.SZArrayHelper.SZGenericArrayEnumerator<T>.

The source code for this class (in Array.cs) has the following comment which partially explains this (remember, all support for generic arrays dates back to a time when IEnumerable<T> was not contraviant)

//--------------------------------------------------------------------------------------- 
// ! READ THIS BEFORE YOU WORK ON THIS CLASS. 
//
// The methods on this class must be written VERY carefully to avoid introducing security holes. 
// That's because they are invoked with special "this"! The "this" object
// for all of these methods are not SZArrayHelper objects. Rather, they are of type U[]
// where U[] is castable to T[]. No actual SZArrayHelper object is ever instantiated. Thus, you will
// see a lot of expressions that cast "this" "T[]". 
//
// This class is needed to allow an SZ array of type T[] to expose IList<T>, 
// IList<T.BaseType>, etc., etc. all the way up to IList<Object>. When the following call is 
// made:
// 
//   ((IList<T>) (new U[n])).SomeIListMethod()
//
// the interface stub dispatcher treats this as a special case, loads up SZArrayHelper,
// finds the corresponding generic method (matched simply by method name), instantiates 
// it for type <T> and executes it.
// 
// The "T" will reflect the interface used to invoke the method. The actual runtime "this" will be 
// array that is castable to "T[]" (i.e. for primitivs and valuetypes, it will be exactly
// "T[]" - for orefs, it may be a "U[]" where U derives from T.) 
//---------------------------------------------------------------------------------------
like image 94
SLaks Avatar answered Oct 05 '22 06:10

SLaks