2011-08-26 7 views
4

以下のコードは、「スキップ」ビットをスキップしてアイテムオブジェクトに「foo/skip/bar」文字列を解析するためのものです。 "foo"と "bar"の項目オブジェクト。実行すると、2つの "棒グラフ"項目が生成されます。 TryGetChild法で .NET IEnumerator <string> yieldブロック内にMoveNextが進まない

、「スキップ」発見されたが、列挙子は前方に「バー」に「スキップ」から移動されます。ただし、実行が呼び出し元のメソッドに戻ると、列挙子は「スキップ」に戻ります。

は私がメインで分割を行う()、それが正常に動作します)(ウォークに列挙子を渡すかのように、これは、いくつかの歩留まりブロックおかしなことだと思います。誰かが列挙者がどのように戻ってくるのか説明できますか?新しいものが作成されていますか?

編集:これは私が私のコードで発見した、一見奇妙な状況の非常に単純化したバージョンです。私は、すでに見つかった回避策を探すのではなく、この疑問を尋ねています。

/* output from program 

enumerator moved to foo 
enumerator moved to skip 
enumerator moved to bar 
enumerator moved to bar 

Item [] (3 items) 

foo 
bar  
bar 
*/  


static void Main() 
{ 
    Walk("foo/skip/bar").ToArray().Dump(); 
} 

private static IEnumerable<Item> Walk(string pathString) 
{ 
    var enumerator = pathString.Split('/').ToList().GetEnumerator(); 
    var current = new Item() { S = "" }; 
    while (enumerator.MoveNext()) 
    { 
     Console.WriteLine("enumerator moved to " + enumerator.Current); 
     yield return current.TryGetChild(enumerator); 
    } 
} 
class Item 
{ 
    public string S { get; set; } 

    public Item TryGetChild(IEnumerator<string> enumerator) 
    { 
     if (enumerator.Current == "skip") 
     { 
      enumerator.MoveNext(); //iterator moves on to 123 
      Console.WriteLine("enumerator moved to " + enumerator.Current); 
     } 
     return new Item() { S = enumerator.Current }; 
    } 
} 
+1

このメソッドを使用する必要がある理由はありますか?あなたの目標ははるかに簡単な方法で達成できるようです。 – dlev

+0

@dlev:編集 – mcintyre321

答えて

4

あなたは、この動作を参照してください理由はList<T>.GetEnumerator()構造体あるList<T>.Enumeratorのインスタンスを返すということです。したがって、あなたはTryGetChild()メソッドに値型を渡す、及び(MoveNext()によって行われたものを含む)は、そのタイプの任意の変異は呼び出し側に反映されないあろう。

+0

くそー、私はちょうど... – Chris

+0

@クリスそれはそれはそこにかなり良い落とし穴だ。ちょうどあなたが最後の文で提案されているものを行うことによって、ILを見て、だけでなく(というわけではないという結論に来たい、それがにISN – dlev

+0

はい、私は「私が決して列挙子を使用しないもう一つの理由」を追加することを検討しました。それはちょうど一見でとても安全であるように見える... :) – Chris

0

私はIEnumerableまたはIEnumerable<T>ループを使用している場合yieldだけうまくいくと思います。

+0

参照IEnumerable ループでも機能します – mcintyre321

+0

「作品のみ」という意味を明確にすることはできますか...別の方法でイテレータを進めようとしていなければ、うまくいきます。 .. – Chris

+0

'yield 'は間違いなく問題です。本当に何が起こっているのか私の答えを見てください。 – dlev

関連する問題