86

どのタイプのクラスがforeachループを使用できますか?

4

7 に答える 7

166

実際、厳密に言えば、使用する必要があるのは、メソッドとプロパティを持つものを返すforeachパブリックメソッドだけです。ただし、これの最も一般的な意味は、「 /を実装し、 /を返すもの」です。GetEnumerator()bool MoveNext()? Current {get;}IEnumerableIEnumerable<T>IEnumeratorIEnumerator<T>

含意によって、これには、、、配列()などのような/を実装するものすべてが含まれます。したがってICollection、標準の「データのコレクション」は通常、をサポートします。ICollection<T>Collection<T>List<T>T[]foreach

最初のポイントを証明するために、以下は問題なく機能します。

using System;
class Foo {
    public int Current { get; private set; }
    private int step;
    public bool MoveNext() {
        if (step >= 5) return false;
        Current = step++;
        return true;
    }
}
class Bar {
    public Foo GetEnumerator() { return new Foo(); }
}
static class Program {
    static void Main() {
        Bar bar = new Bar();
        foreach (int item in bar) {
            Console.WriteLine(item);
        }
    }
}

それはどのように機能しますか?

foreach(int i in obj) {...}ちょっとのようなforeachループは次のようになります。

var tmp = obj.GetEnumerator();
int i; // up to C# 4.0
while(tmp.MoveNext()) {
    int i; // C# 5.0
    i = tmp.Current;
    {...} // your code
}

ただし、バリエーションがあります。たとえば、列挙子(tmp)がをサポートしIDisposableている場合は、それも使用されます(と同様using)。

ループの内側(C#5.0)と外側(C#4.0まで)の宣言" int i"の配置の違いに注意してください。コードブロック内で匿名メソッド/ラムダで使用する場合は重要です。しかし、それは別の話です;-pi

于 2008-12-29T23:01:43.240 に答える
7

MSDNから:

このステートメントは、配列またはオブジェクトコレクションforeach内の要素ごとに埋め込みステートメントのグループを繰り返します。このステートメントは、コレクションを反復処理して目的の情報を取得するために使用されますが、予期しない副作用を回避するためにコレクションの内容を変更するために使用しないでください。(私の強調)foreach

したがって、配列がある場合は、次のようにforeachステートメントを使用して配列を反復処理できます。

 int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };
    foreach (int i in fibarray)
    {
        System.Console.WriteLine(i);
    }

List<T>次のように、コレクションを反復処理するためにも使用できます。

List<string> list = new List<string>();

foreach (string item in list)
{
    Console.WriteLine(item);
}
于 2008-12-29T22:55:11.770 に答える
4

ブログ投稿Duck Notationによると、ダックタイピングが使用されています。

于 2008-12-29T23:12:54.857 に答える
2

ドキュメントは次のとおりです。 主な記事 With Arrays With Collection Objects

「コレクション要素の型は識別子型に変換可能でなければならない」ことに注意することが重要です。これは、コンパイル時にチェックできない場合があり、インスタンス型が参照型に割り当てられない場合、実行時例外が生成される可能性があります。

オレンジなど、フルーツ バスケットに Apple 以外のものがある場合、実行時例外が生成されます。

List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() };
foreach(Apple a in fruitBasket)

これは、 Enumerable.OfTypeを使用してリストを Apple のみに安全にフィルタリングします。

foreach(Apple a in fruitBasket.OfType<Apple>() )
于 2008-12-29T23:24:50.307 に答える