次のクラスを想定します。
public class MyEnum: IEnumerator
{
private List<SomeObject> _myList = new List<SomeObject>();
...
}
MyEnumにIEnumeratorメソッドを実装する必要があります。しかし、IEnumeratorメソッドを実装する必要なしに、IEnumeratorの実装を直接_myListに「委任」またはリダイレクトすることは可能ですか?
方法1: 引き続きカプセル化を使用し、呼び出しをList実装に転送します。
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();
}
}
方法2: リストの実装から継承すると、その動作を無料で取得できます。
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();
}
}
方法1では、MyEnumの知識がなくてもリストで呼び出されるメソッドがないため、サンドボックス化が向上します。最小限の労力で方法2が推奨されます。
あなたはこれを行うことができます:
public class MyEnum : IEnumerator {
private List<SomeObject> _myList = new List<SomeObject>();
public IEnumerator GetEnumerator() { return this._myList.GetEnumerator(); }
}
理由は簡単です。クラスにはコレクションであるいくつかのフィールドを含めることができるため、コンパイラ/環境は「IEnumerator」の実装に使用するフィールドを認識できません。
EIDT:@pbに同意します-IEnumerator<SomeObject>インターフェイスを実装する必要があります。
pbのメソッドを使用することを除けば、これは「単純な」理由で不可能です。インターフェイスメソッドはthis
、最初の引数としてポインタを渡す必要があります。オブジェクトを呼び出すとGetEnumerator
、このポインタがオブジェクトになります。ただし、呼び出しがネストされたリストで機能するためには、ポインタはクラスではなく、そのリストへの参照である必要があります。
したがって、メソッドを他のオブジェクトに明示的に委任する必要があります。
(ちなみに、他の返信のアドバイスは正しかった:使用するIEnumerator<T>
、ではない IEnumerable
!)
呼び出し元がコレクションを変更できない方法でコレクションを返したい場合は、リストをReadOnlyCollection <>にラップし、ReadOnlyCollection<>のIEnumerable<>を返すことができます。
このようにして、コレクションが変更されないようにすることができます。
List<T>から派生しない限りではありません。
public class MyEnum : List<SomeObject>, IEnumerable<SomeObject>{}
ご意見・ご説明ありがとうございました。最終的に、私はあなたの答えのいくつかを以下にまとめました:
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();
}
}
この解決策は、呼び出し元のコードがリストを変更できないようにし、各列挙子があらゆる点で他の列挙子から独立していることを確認することです(ソートなど)。再度、感謝します。