myGrid.Rows
タイプDataGridViewRowCollection
です。
これはかなり古いもので、その定義は次のとおりです。
public class DataGridViewRowCollection : ICollection, IEnumerable, IList
非汎用インターフェースが表示されますか? このクラスは実装でき、そのまま機能IList<DataGridViewRow>
しvar
ますが、レガシーです。
IEnumerable
アイテムタイプに関する情報を伝えません。関数は を返す可能性がありますが、 をGetEnumerator
返すため、ここでは役に立ちません。IEnumerator
IEnumerator<DataGridViewRow>
基本的に、C# コンパイラは、関数とプロパティ (明示的に実装されている場合は/インターフェイス)GetEnumerator
を持つオブジェクトを返す関数を探します。このダックタイピングのアプローチは、歴史的な理由によるものであり、ジェネリックが言語に導入される前に存在していました。ループ変数は、プロパティと同じ型になります。そして(非ジェネリックバリアント) の中で、タイプはです。MoveNext
Current
IEnumerable<T>
IEnumerable
foreach
Current
IEnumerator
Current
object
タイプを明示的に指定する:
foreach (DataGridViewRow row in myGrid.Rows)
より良いメカニズムがないため、単に の戻り値を にキャストしますCurrent
。DataGridViewRow
ここでそのキーワードを本当に使用したい場合は、LINQ を使用して同じ効果を達成することもできます。var
foreach (var row in myGrid.Rows.Cast<DataGridViewRow>())
これは機能します。拡張メソッドが を返し、それが を利用し、最終的に列挙子のプロパティの型になるため、型情報が伝播されるからです。Enumerable.Cast<T>
IEnumerable<T>
IEnumerator<T>
T
Current
この時点でこれらの詳細が役立つとは思えませんが、この言語についてさらに学習する際に参照できるように保管しておくことをお勧めします。これを理解するには、拡張メソッドとジェネリック型について学ぶ必要があります。