9

したがって、このコードが機能することに気づきました。

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";
    }
}

using特に、次の理由から、ブロックについて興味があります。

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

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

}

コンパイラエラーで失敗します。明らかに、yield return返されるクラスIDisposableは通常の配列列挙子ではありません。だから今私は興味があります:正確には何がyield return作成されますか?

4

1 に答える 1

11

IEnumerator<T>IDisposableオブジェクトブラウザまたはMSDNで確認できるように、を実装します。

非ジェネリックIEnumeratorはそうではありません。

基本Arrayクラスは実装しますが、実装IEnumerableしませんIEnumerable<T>。(Arrayジェネリックではないため)
具象配列型は実装しますIEnumerable<T>が、明示的に実装しますGetEnumerator()(理由はわかりません)。
したがって、GetEnumerator()任意の配列タイプのvisibleは。を返しますIEnumerator

一般的なIEnumerable<T>実装はを返しますSystem.SZArrayHelper.SZGenericArrayEnumerator<T>

このクラス(のArray.cs)のソースコードには、これを部分的に説明する次のコメントがあります(ジェネリック配列のすべてのサポートは、矛盾していなかった時代にさかのぼることをIEnumerable<T>忘れないでください)

//--------------------------------------------------------------------------------------- 
// ! 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.) 
//---------------------------------------------------------------------------------------
于 2013-03-11T15:05:30.577 に答える