Frage

Angenommen

die folgende Klasse:

public class MyEnum: IEnumerator
{
    private List<SomeObject> _myList = new List<SomeObject>();
...
}

Es ist notwendig, die IEnumerator Methoden in MyEnum zu implementieren. Aber ist es möglich, zu ‚delegieren‘ oder die Implementierung für IEnumerator umleiten direkt an _myList ohne dass die IEnumerator Methoden implementieren?

War es hilfreich?

Lösung

Methode 1: Weiter zur Verkapselung und Vorwärts-Anrufe auf die Liste Implementierung verwenden.

class SomeObject
{
}

class MyEnum : IEnumerable<SomeObject>
{
    private List<SomeObject> _myList = new List<SomeObject>();

    public void Add(SomeObject o)
    {
        _myList.Add(o);
    }

    public IEnumerator<SomeObject> GetEnumerator()
    {
        return _myList.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyEnum a = new MyEnum();
        a.Add(new SomeObject());

        foreach (SomeObject o in a)
        {
            Console.WriteLine(o.GetType().ToString());
        }

        Console.ReadLine();
    }
}

Methode 2: Vererben von List Implementierung Sie dieses Verhalten kostenlos.

class SomeObject
{
}

class MyEnum : List<SomeObject>
{
}

class Program
{
    static void Main(string[] args)
    {
        MyEnum a = new MyEnum();
        a.Add(new SomeObject());

        foreach (SomeObject o in a)
        {
            Console.WriteLine(o.GetType().ToString());
        }

        Console.ReadLine();
    }
}

Methode 1 für eine bessere Sandbox ermöglicht es, da es keine Methode, die ohne MyEnum Wissen in Liste aufgerufen werden. Für die am wenigsten Aufwand Methode 2 bevorzugt wird.

Andere Tipps

Sie können dies tun:

public class MyEnum : IEnumerator {
    private List<SomeObject> _myList = new List<SomeObject>();
    public IEnumerator GetEnumerator() { return this._myList.GetEnumerator(); }
}

Der Grund ist einfach. Ihre Klasse Dose enthält mehrere Felder, die Sammlungen sind, so Compiler / Umwelt kann nicht wissen, welches Feld für die Umsetzung „IEnumerator“ verwendet werden soll.

EIDT:. ich mit @pb zustimmen - sollten Sie implementiert IEnumerator Schnittstelle

Neben pb Methode verwendet wird, ist dies nicht möglich, dass ein „einfacher“ Grund: die Interface-Methode muss einen this Zeiger als erstes Argument übergeben bekommen. Wenn Sie GetEnumerator auf Ihrem Objekt aufrufen, wird dieser Zeiger Ihr Objekt sein. Doch für den Aufruf, um auf der verschachtelten Liste zu arbeiten, würde der Zeiger hat ein Verweis auf diese Liste sein, nicht die Klasse.

Deshalb müssen Sie explizit die Methode auf das andere Objekt übertragen.

(Und übrigens, die Beratung in der anderen Antwort richtig war: Verwendung IEnumerator<T>, nicht IEnumerable)

Wenn Sie eine Sammlung in einer Art und Weise zurückkehren wollen, wo der Anrufer nicht in der Lage ist, die Sammlung zu ändern, könnten Sie die Liste in eine Readonlycollection wickeln möchten <> und Rückkehr IEnumerable <> des Readonlycollection <>.

Auf diese Weise können Sie Ihre Sammlung sicher sein, nicht geändert werden.

Es sei denn, Sie leiten sich von List .

public class MyEnum : List<SomeObject>, IEnumerable<SomeObject>{}

Vielen Dank für Ihre Eingabe und Erklärungen. Schließlich habe ich einige Ihrer Antworten auf die folgende Kombination:

    class MyEnum : IEnumerable<SomeObject>
{
    private List<SomeObject> _myList = new List<SomeObject>();
    public IEnumerator<SomeObject> GetEnumerator()
    {
        // Create a read-only copy of the list.
        ReadOnlyCollection<CustomDevice> items = new ReadOnlyCollection<CustomDevice>(_myList);
        return items.GetEnumerator();
    }
}

Diese Lösung ist der aufrufende Code ist zum Modifizieren der Liste nicht in der Lage, um sicherzustellen, und jeder Enumerator ist unabhängig von den anderen in jeder Hinsicht (zum Beispiel mit Sortierung). Nochmals vielen Dank.

Beachten Sie, dass dank duck-typing können Sie foreach auf ein beliebiges Objekt verwenden, die eine GetEnumerator Methode hat -. der Objekttyp IEnumerable nicht tatsächlich umsetzen muss

Also, wenn Sie dies tun:

class SomeObject
{
}

 class MyEnum
 {
    private List<SomeObject> _myList = new List<SomeObject>();

    public IEnumerator<SomeObject> GetEnumerator()
    {
        return _myList.GetEnumerator();
    }
 }

Dann funktioniert das ganz gut:

MyEnum objects = new MyEnum();
// ... add some objects
foreach (SomeObject obj in objects)
{
    Console.WriteLine(obj.ToString());
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top