4

わかりましたので、私はIEnumeratorandを処理していましたIEnumerable。現在、MSDN によると、これらの主な目的は、顧客のコレクションを反復処理することです。

ただし、どちらも使用せずにカスタムコレクションを反復処理できました(または、少なくともそう思いたいです)。

namespace ienumerator
{

class person
{
    public person(string first, string second)
    {
        fname = first;
        lname = second;
    }
    public string fname { get; set; }
    public string lname { get; set; }
}

class person_list
{
    public person[] list;
    public person_list(person[] per)
    {
        list = new person[per.Length];
        for (int i = 0; i < per.Length; i++)
        {
            list[i] = per[i];
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        person[] names = new person[3]
        {
            new person("some","one"),
            new person("another","one"),
            new person("sss","ssdad"),
        };

        person_list list_of_names = new person_list(names);
        int i = 0;
        while (i < list_of_names.list.Length)
        {
            Console.WriteLine(list_of_names.list[i].fname);
            i++;
        }
        Console.Read();
    }
 }
}

したがって、私の理解に欠陥があるのは、上記は、実装後に達成したのと同じ結果を私に与えていIEnumeratorますIEnumerable.

4

5 に答える 5

18

ただし、どちらも使用せずにカスタムコレクションを反復処理できました

もちろん、インターフェースなしで独自のコレクションを繰り返すことができます。できない場合は、どのようにインターフェイスを実装しますか?

コードの実装者は、便宜上インターフェイスを実装していません。コードの消費者の利便性のために実装します。このインターフェースは、「お客様への注意: 実装方法について何も知らなくても、このコレクションの内容を列挙できます」という意味です。

それがインターフェースの目的です。それは、コードの消費者がその仕組みを理解することなく使用できるようにする抽象化を提供します。

于 2012-12-16T16:49:05.360 に答える
2

あなたのmain関数でperson_listは、人のリストを反復処理するためにの 2 つの側面を使用し、特定の位置でコレクションのメンバーを取得するためLength[]演算子を使用しました。

ただし、これらのいずれかまたは両方を実装していないコンテナーまたはカスタム コレクションがある場合はどうなるでしょうか。たとえば、ファイルを 1 行ずつ読み取るクラスは、コレクションの長さが事前にわからないため、定義しない場合がありますLength。キューからメッセージを読み取る列挙子は、次のものしか取得できない場合があり、たとえば、4 桁先の[4]. どちらの場合でも、コレクションを適切に「反復」できます。

IEnumeratorIEnumerable機能するために必要な属性を正確に必要とし、foreach他には必要ありません。これが、関数がそれらを要件として使用できる理由であり、渡されたコレクションのタイプを反復処理できることを知っています。

于 2012-12-16T14:47:44.307 に答える
1

もちろん、インターフェイスを実装せずにカスタム コレクションを反復処理することもできIEnumerableますが、反復コードはカスタム コレクションを認識している必要があります。

を実装するIEnumerableと、すべての要素を反復処理するコードはクラスを認識する必要がなくなりますperson_list。を実装するクラスのインスタンスを使用しますが、実際のインスタンスを後でIEnumerable実装する別のものに交換しても機能します。IEnumerable

于 2012-12-16T14:42:00.483 に答える
0

カスタム シーケンスを反復する方法はたくさんあります。これを行う 1 つの方法は、Iterator Design Patternを使用することです。

Iterator パターンは、カスタム シーケンス (メモリ内のコレクション、生成されたコレクションなど) のトラバースを統一するために使用されます。.NET の世界では、このパターンは次のように実装されます。インターフェイスを実装する反復可能なオブジェクトがありIEnumerableます (これは、クラスのすべての顧客に対して、コンテンツをトラバースする能力があることを示します)。

IEnumeratorそして、反復可能なオブジェクトの現在の位置への「ポインター」として扱うことができるイテレーター自体 (インターフェースを実装するオブジェクト) があります。内部ループ (つまり、同じオブジェクトを一度に複数回繰り返す) がある可能性があるため、イテレータから反復可能なオブジェクトを分割する必要があります。

基本的に、特定のシーケンスをトラバースする方法はたくさんありますが、反復子パターンを使用すると、このアプローチを「一般化」して、トラバース アルゴリズムの特定の実装を実装内の呼び出し元から隠すことができます。

于 2012-12-19T20:52:20.267 に答える