私の状況はこれです。複数の異なるタイプのオブジェクトに対していくつかの検証とメッセージタイプのコードを実行する必要がありますが、クリーンさ (およびコードの再利用) のために、オブジェクトに関係なく、この検証へのすべての呼び出しが基本的に同じに見えるようにしたいと考えています。オーバーロードによってこれを解決しようとしていますが、ジェネリック コレクション オブジェクトに到達するまで問題なく動作します。
次の例は、ここで話していることを明確にする必要があります。
private string DoStuff(string tmp) { ... }
private ObjectA DoStuff(ObjectA tmp) { ... }
private ObjectB DoStuff(ObjectB tmp) { ... }
...
private Collection<ObjectA> DoStuff(Collection<ObjectA> tmp) {
foreach (ObjectA obj in tmp) if (DoStuff(obj) == null) tmp.Remove(obj);
if (tmp.Count == 0) return null;
return tmp;
}
private Collection<Object> DoStuff(Collection<ObjectB> tmp) {
foreach (ObjectB obj in tmp) if (DoStuff(obj) == null) tmp.Remove(obj);
if (tmp.Count == 0) return null;
return tmp;
}
...
Collection<T>
異なるタイプごとにまったく同じコードを複製する必要があるため、これは本当に無駄のように思えます。それぞれに個別のインスタンスを作成するのではなく、DoStuff
any を処理する単一のインスタンスを作成したいと思います。Collection<T>
を使用してみICollection
ましたが、これには 2 つの問題があります。1 つ目は、メソッドをICollection
公開していないことと、リスト内のオブジェクトの型がわからないため、ループを記述できないことです。を受け入れるメソッドがないため、 のようなより一般的なものを使用しても機能しません。実際のオブジェクトに適切なメソッドを呼び出す必要があります。適切なメソッドを選択し、適切にキャストするために if ステートメントのある種の巨大なリストを取得して実行するメソッドを作成すると、冗長なコードを取り除くという考え全体が無効になります。これらのメソッドをすべてコピーして貼り付けるだけでもかまいません。.Remove
foreach
object
DoStuff
object
DoStuff
object
Collection<T>
一般的な方法を使用してみましたが、これにはループDoStuff<T>
で同じ問題があります。foreach
設計時にはオブジェクトの型がわからないため、コンパイラは を呼び出させませんDoStuff(obj)
。
技術的には、コンパイラはコンパイル時にどの呼び出しを行う必要があるかを判断できる必要があります。これらはすべてプライベート メソッドであり、呼び出しで渡されるオブジェクトの特定の型は、メソッドが呼び出された時点ですべてわかっているためです。その知識は、このメソッドによって呼び出された後のメソッドには反映されていないようです。
ここではリフレクションを使用したくありません。すべてのCollection<T>
メソッドをコピーして貼り付けるよりもコードがさらに複雑になり、パフォーマンスが低下するからです。何か案は?
---編集 1--- 山かっこの html コードを使用していなかったため、ジェネリック メソッド参照が正しく表示されていないことに気付きました。これは今すぐ修正する必要があります。
---編集 2--- 以下の応答に基づいて、Collection<T>
メソッドを次のように変更しました。
private Collection<T> DoStuff<T>(Collection<T> tmp) {
for (int i = tmp.Count - 1; i >= 0; i--) if (DoStuff(tmp[i]) == null) tmp.RemoveAt(i);
if (tmp.Count == 0) return null;
return tmp;
}
ただし、これはまだ機能しません。コンパイラは、 を呼び出すときにどのオーバーロードされたメソッドを呼び出すかを判断できないためDoStuff(tmp[i])
です。