関数 GetEnumeratorInFirstStyle、GetEnumeratorInSecondStyle などを作成することから始めて (もちろん、アプリケーションに適した名前を使用してください)、次のような新しい構造を作成することをお勧めします (vb 構文の例ですが、C# に簡単に変換できるはずです)。
クラス enumTest
関数 GetEnumeratorInFirstStyle() As IEnumerator(Of Integer)
Return Enumerable.Empty(Of Integer)() ' 実際のコードはもっと良いことをするでしょう
終了機能
プライベート構造体 FirstStyleEnumerable
IEnumerable(Of Integer) を実装します
プライベート myEnumTest As enumTest
Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer) System.Collections.Generic.IEnumerable(Of Integer).GetEnumerator を実装
myEnumTest.GetEnumeratorInFirstStyle を返します
終了機能
パブリック関数 GetEnumerator1() System.Collections.IEnumerator として実装 System.Collections.IEnumerable.GetEnumerator
myEnumTest.GetEnumeratorInFirstStyle を返します
終了機能
Sub New(ByVal newEnumTest As enumTest)
myEnumTest = newEnumTest
サブ終了
末端構造
Public ReadOnly プロパティ AsFirstStyleEnumerable As IEnumerable(Of Integer)
得る
新しい FirstStyleEnumerable(Me) を返す
エンドゲット
End プロパティ
クラス終了
クラスではなく構造体が使用されることに注意してください。クラスを使用すると、新しいヒープ オブジェクトを作成する必要があり、そのアクセスに余分なレベルの間接性が追加されるためです。構造体の本当の目的は、カプセル化されたオブジェクトとは「異なる」IEnumerable<T> を実装できるようにすることです。ところで、列挙のバリエーションごとに新しい FirstStyleEnumerator 構造体を手動で定義する必要がないように、マーカー クラスでジェネリックを使用することは可能です。ただし、それがよりクリーンになるか、より混乱するかはわかりません。
インターフェース IQualifiedEnumerable(Of T, U)
関数 GetEnumerator() As IEnumerable(Of U)
終了インターフェイス
構造体 QualifiedEnumerableWrapper(Of T, U)
IEnumerable(Of U) を実装します
Private myEnumerable As IQualifiedEnumerable(Of T, U)
Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of U) 実装 System.Collections.Generic.IEnumerable(Of U).GetEnumerator
myEnumerable.GetEnumerator を返します
終了機能
パブリック関数 GetEnumerator1() System.Collections.IEnumerator として実装 System.Collections.IEnumerable.GetEnumerator
myEnumerable.GetEnumerator を返します
終了機能
Sub New(ByVal newEnumerable As IQualifiedEnumerable(Of T, U))
myEnumerable = newEnumerable
サブ終了
末端構造
クラス EnumTest2
IQualifiedEnumerable(Of FirstEnumerationStyle, Integer) を実装します
IQualifiedEnumerable(Of SecondEnumerationStyle, Integer) を実装します
Private Class FirstEnumerationStyle ' ジェネリックのマーカー クラス
クラス終了
プライベート クラス SecondEnumerationStyle
クラス終了
Private Function GetFirstStyleEnumerator() As System.Collections.Generic.IEnumerable(Of Integer) IQualifiedEnumerable(Of FirstEnumerationStyle, Integer).GetEnumerator を実装
Enumerable.Empty(Of Integer)() を返す
終了機能
プライベート関数 GetSecondStyleEnumerator() は System.Collections.Generic.IEnumerable(Of Integer) として IQualifiedEnumerable(Of SecondEnumerationStyle, Integer).GetEnumerator を実装します
Enumerable.Empty(Of Integer)() を返す
終了機能
Public ReadOnly プロパティ AsFirstStyleEnumerable As IEnumerable(Of Integer)
得る
新しい QualifiedEnumerableWrapper(Of FirstEnumerationStyle, Integer) を返します
エンドゲット
End プロパティ
Public ReadOnly プロパティ AsSecondStyleEnumerable As IEnumerable(Of Integer)
得る
新しい QualifiedEnumerableWrapper(Of SecondEnumerationStyle, Integer) を返します
エンドゲット
End プロパティ
クラス終了
ここで、インターフェースと構造体の定義は完全に汎用的です。列挙の各追加メソッドをクラスに追加するには、その列挙子を返す関数と、適切な型の QualifiedEnumerableWrapper を返すプロパティを追加する必要があります。