2016-04-12 12 views
0

私はこのコードを持っていた:Resharperがコード変更を提案し、変更に不平を言うのはなぜですか?

return children.SelectMany(c => GetChildControls<TControl>(c)).Concat(children); 

を...とReSharperのは、私がこれまでそれを変更提案:あなたはおそらく見たように、

internal static IEnumerable<TControl> GetChildControls<TControl>(this Control control) where TControl : Control 
{ 
    var children = control.Controls != null ? control.Controls.OfType<TControl>() : Enumerable.Empty<TControl>(); 
    return children.SelectMany(GetChildControls<TControl>).Concat(children); 
} 

違い:文脈では

return children.SelectMany(GetChildControls<TControl>).Concat(children); 

その行の "改良された"バージョンが挿入された "(c)"を省略したということです。

しかし、疑わしいものとして、「IEnumerableの複数の列挙が可能です」

ええ、そうかもしれませんが、それは複数でもよいはずですが、それはなぜですか?私はそれを以前の状態に戻すべきですか?

+0

私の推測では、Resharperは各行に対して一度に示唆するコード変更の数に制限があると思います。 "可能な複数の列挙"の問題は、コードの両方のバージョンに存在しますが、Resharperは、「改善」が行われ、そのメッセージがなくなると、それを表示します。 –

答えて

2

ReSharperがあなたのために拾っている問題は、childrenを2回列挙していることです。具体的にはchildren.SelectMany(GetChildControls<TControl>)に初めてchildrenを、もう1度に.Concat(children)と呼ぶと列挙します。 ReSharperは、各列挙が異なる結果になる可能性があるため、または各列挙にコストがかかる可能性があるため、これについて警告します。詳細はthis questionを参照してください。

一つの解決策は、childrenが(もちろん、あなたがそれ自身を変異させ、場合を除き)あなたがそれを作成した後、あなたのメソッド内で変動し、それが一度だけ列挙されることはありませんを確認します

internal static IEnumerable<TControl> GetChildControls<TControl>(this Control control) where TControl : Control 
{ 
    var children = control.Controls.OfType<TControl>().ToList(); 
    return children.SelectMany(GetChildControls<TControl>).Concat(children); 
} 

だろう。

+0

コードでは、 "メソッドの型引数System.Linq.Enumerable.SelectMany (System.Collections.Generic.IEnumerable 、System.Func >) 'を使用から推測することはできません。型引数を明示的に指定してみてください\t " –

+0

申し訳ありません!私はあなたの拡張メソッドが 'this TControl'の代わりに' this Control'であることに気付きませんでした。更新された回答がうまくいくはず – AGB

関連する問題