What kind of class does yield return return

c#

Solution

`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.) 
//---------------------------------------------------------------------------------------

Problem

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?

Original source

Related problems