問題タブ [ienumerator]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
.net-2.0 - 重複するメンバー名を必要とするインターフェイスを実装する方法は?
コードなどにいくつかのインターフェイスを実装する必要があることがよくありIEnumerable<T>
ます。
毎回、自動的に実装するときに、次のことが発生します。
両方のGetEnumerator()メソッドを実装する必要がありますが、どうにかして同じことを行うことがわかっていても、同じ名前を持つことは不可能です。コンパイラは、戻り値の型のみが異なるため、一方を他方のオーバーロードとして扱うことができません。
そうするとき、GetEnumerator1()
アクセサをに設定することができprivate
ます。このように、コンパイラはインターフェイス メンバーを実装していないことについて文句を言うことはありませんNotImplementedException
。メソッドの本体内で a をスローするだけです。
しかし、それは良い習慣なのか、それとも別の方法で進めるべきなのか、おそらくメソッド エイリアスか何かではないかと思います。
IEnumerable<T>
同じ名前の2つの異なるメソッドの実装を必要とするようなインターフェースを実装する際の最良のアプローチは何ですか?
編集#1
VB.NET はインターフェイスを実装する際に C# とは異なる反応を示しますか?VB.NET では明示的に実装されているため、
GetEnumerator1()
. コードは次のとおりです。
どちらのGetEnumerator()
メソッドも明示的に実装されており、コンパイルはそれらが同じ名前を持つことを拒否します。なんで?
.net - IEnumerator:空のDisposeメソッドがあるのは正常ですか?
ラッパーしているCOMコレクションをIEnumerator<T>
反復処理するクラスを作成しています。が拡張されていることに気付いたので、メソッド を実装する必要があります。IEnumerator<T>
IDisposable
Dispose
ただし、コレクション(の最後に配置したくないforeach
)とint
インデックスへの参照しかないため、そこに配置するものは何も考えられません。Dispose
メソッドを空のままにしておくのは正常ですか?
c# - BCL コレクションがクラスではなく構造体列挙子を使用するのはなぜですか?
変更可能な構造体が一般的に悪であることは誰もが知っています。IEnumerable<T>.GetEnumerator()
また、 type を返すためIEnumerator<T>
、構造体はすぐに参照型にボックス化され、最初から単に参照型である場合よりも多くのコストがかかると確信しています。
では、なぜ BCL ジェネリック コレクションでは、すべての列挙子が変更可能な構造体なのでしょうか? きっと、それなりの理由があったに違いない。私が思いつく唯一のことは、構造体を簡単にコピーできるため、任意の時点で列挙子の状態を保持できることです。しかしCopy()
、インターフェイスにメソッドを追加するIEnumerator
ことはそれほど面倒ではなかったので、これ自体が論理的な正当化であるとは思えません。
デザインの決定に同意しなくても、その背後にある理由を理解できるようになりたい.
c# - IEnumeratorを使用するためのパターンインターフェイスで
一連のメソッド()全体で一連のアイテム()を処理する必要があるC#クラスがあるIEnumerable<T>
ため、メソッド内で単純に処理することはできませんforeach
。私はこれを呼び出し.GetEnumerator()
て渡します。これIEnumerator<T>
は非常にうまく機能し、単一のシーケンスをループするときに必要な柔軟性を提供します。
ここで、他の人がこのプロセスにロジックを追加できるようにします。これを行う最も自然な方法は、を受け入れるメソッドとのインターフェースを提供することIEnumerator<T>
です。簡単、完了、そしてそれは機能します。
しかし、これがアンチパターンであることが心配です。彼らは、IEnumerator<T>
がすでに.MoveNext()
電話をかけていることを知っている必要があるので、簡単にアクセスできます.Current
。IEnumerator<T>
加えて、実装されるインターフェースで使用する前例は見当たりません。
- 私が考慮していない落とし穴は何ですか?
- それ自体を公開せずに、これと同じ効率的なメカニズム(つまり、複数のコピーを作成/破棄したくない)を可能にする別のパターンはあり
IEnumerator<T>
ますか?
更新:以下のコメントで述べたように:私が欲しいのはある種の一般的なものStream<T>
です。次のアイテムを効果的に見て(IEnumerator.Current
-> .Peek()
)、それを消費できるようにする必要があります(IEnumerator<T>.MoveNext()
-> .Pop()
)。
IEnumerator<T>
ビルのインターフェースにぴったり合うので使用しました。私は一般的なBCLタイプを適切なときに使用することを好みますが、これを悪用しているように見えました。
それで質問3)このニーズに合うクラスはありますか?IEnumerator<T>
または、内部で遅延実行する独自のストリームを作成する必要がありますか?その後、完全にカプセル化されます。既存のコレクションの多くは内部ストレージを備えているため使用したくないのですが、ストレージはIEnumerable<T>
iteslfにしたいのです。
OK、コンセンサスは、IEnumerator<T>
多くの場合ValueType
、の状態を事前に知らないだけでなく、IEnumerator<T>
それを渡すことは一般的に悪い考えであるということのように聞こえます。
私が聞いた中で最も良い提案は、渡される独自のクラスを作成することです。他に何か提案はありますか?
c# - コードのこの部分の動作
アップデート。こんにちは、私は以下のコードがどのように機能しているか知っています。cross と circle が Cross() と Circle() メソッドを指していることは知っています。しかし、コードのこの部分については、まだ少し混乱しています。説明してもらえますか?
すべてのコード
c# - IEnumeratorの実装の問題
私はこのコードを持っています:
コンパイルするとき-すべてが良いですが、クラスを呼び出すとき:
次の問題が発生しています: http ://screencast.com/t/NDBkNTNkMjkt
修正する方法はありますか?
ありがとう、ドミトリー
c# - このコードは、リアクティブ フレームワークを使用してリファクタリングできますか?
次のコードをコピーして、新しい C# コンソール アプリに貼り付けます。
2 スレッド (A、B)
スレッドは一度に 1 つのインスタンスを提供でき、Set メソッドを呼び出します B スレッドは一連のインスタンスを受け取りたい (スレッド A によって提供される)
したがって、文字通り Add(item)、Add(item)、.. を異なるスレッド間で IEnumerable に変換する
もちろん、他のソリューションも大歓迎です!
c# - IEnumerable の複数の列挙子
内部にオブジェクト生成の多くのモードがあるカスタムメイドのコレクションがあります。
一度に 1 つのオブジェクトまたは一度に N 個のオブジェクトを生成できます。
実行時に生成の実装を切り替えたり、新しいものを作成したりするオプションが欲しいです。
私はこの種の構文で何かを探しています:
私の問題は次のとおりです。
何が返されるのかわかりませんEnumerateAs()
か?私はそれが IEnumerator だと仮定していますが、それでも私のリストの列挙子になりますか?
LazyEnumerator は IEnumerator を継承していますか?
myCollection をどのように認識していますか?
c# - C# の IEnumerator.GetEnumerator に関する質問
方法について質問がありIEnumerator.GetEnumerator()
ます。
コンパイルしようとすると、エラーメッセージが表示されます
'System.Collections.IEnumerator' には 'GetEnumerator' の定義が含まれておらず、タイプ 'System.Collections.IEnumerator' の最初の引数を受け入れる拡張メソッド 'GetEnumerator' が見つかりませんでした (using ディレクティブまたはアセンブリ参照がありませんか? ?)
コードに何か問題がありますか?
前もって感謝します
君たちありがとう。わかった。
c# - 1 つの GetEnumerator しか定義できないのに、なぜ IEnumerable(T) を実装するのですか?
更新: 基本的に全会一致の反対意見で構成されたすべてのコメントに感謝します。提起されたすべての反論は有効でしたが、棺桶の最終的な釘は、最終的には、このアイデアが表面上提供したわずかな利点でさえ、定型コードの排除という事実によって無効にされたというアニの鋭い観察であったと思います。アイデア自体には、独自のボイラープレート コードが必要です。
ええ、私が確信していると考えてください。それは悪い考えです。
そして、私の尊厳をいくらか救うために:私は議論のためにそれを演じたかもしれませんが、そもそもこのアイデアに本当に納得したことはありませんでした. 本音。
この質問をばかげているとして却下する前に、次のことを検討してください。
IEnumerable<T>
from* を継承しますIEnumerable
。つまり、実装する型はIEnumerable<T>
一般にと(明示的に)の両方 を実装する必要があります。これは基本的に定型コードに相当します。IEnumerable<T>.GetEnumerator
IEnumerable.GetEnumerator
- そのメソッドがメソッドとプロパティを持つ何らかの型のオブジェクトを返す限り
foreach
、メソッドを持つ任意の型を上書きできます。したがって、型がシグネチャを持つ1 つのメソッドを定義している場合、 を使用してそれを列挙することは合法です。GetEnumerator
MoveNext
Current
public IEnumerator<T> GetEnumerator()
foreach
- 明らかに、インターフェイスを必要とする多くのコードがあり
IEnumerable<T>
ます。たとえば、基本的にすべての LINQ 拡張メソッドです。幸いなことに、C# がキーワードを介して提供する自動反復子生成を使用すると、可能な型からforeach
に移行するのは簡単です。IEnumerable<T>
yield
これをすべてまとめると、次のような独自のインターフェースを定義するとどうなるかというクレイジーなアイデアが浮かびました。
次に、列挙可能にしたい型を定義するたびに、 の代わりにこのインターフェイスを実装し、2 つのメソッド (1 つは明示的)IEnumerable<T>
を実装する必要がなくなります。GetEnumerator
例えば:
最後に、この型をインターフェイスを必要とするコードと互換性を持たせるために、次のIEnumerable<T>
ように拡張メソッドを定義して、 anyIForEachable<T>
から anに移動することができますIEnumerable<T>
。
これを行うことで、あらゆる方法で の実装として使用できる型を設計できるようになりますが、それぞれのIEnumerable<T>
厄介な明示的なIEnumerable.GetEnumerator
実装は必要ありません。
例えば:
皆さんは、このアイデアについてどう思いますか? これが間違いである理由を見逃していますか?
最初はそれほど大したことではないものの、おそらく非常に複雑なソリューションのように思えることを私は認識しています(インターフェースを明示的に定義する必要があることを本当に気にかけている人はいないと思いIEnumerable
ます)。しかし、それは頭に浮かんだだけで、このアプローチがもたらす明らかな問題は見られません。
一般に、少量のコードを何度も書かなければならないという手間を省くために、適度な量のコードを 1 回書くことができれば、それだけの価値があります。
*それは使用する正しい用語ですか? あるインターフェイスが別のインターフェイスを「継承する」と言うのはいつも躊躇します。でも当たってるかも。