3

次のコードを検討してください。

abstract class SomeClassX<T>
{
  // blah
}

class SomeClassY: SomeClassX<int>
{
  // blah
}

class SomeClassZ: SomeClassX<long>
{
  // blah
}

SomeClassX<T> のコレクションが必要ですが、 SomeClassX<int> != SomeClassX<long> および List<SomeClassX<>> が許可されていないため、これは不可能です。

したがって、私の解決策は、 SomeClassX<T> にインターフェイスを実装させ、コレクションを次のように定義することです。ここで、ISomeClassX はインターフェイスです。

class CollectionOfSomeClassX: List<ISomeClassX>
{
  // blah
}

これはこれを行うための最良の方法ですか、それともより良い方法はありますか?

4

2 に答える 2

1

あなたが提案したインターフェースを使用するか、 SomeClassX を別のクラスから継承させます。コレクション内のオブジェクトで何をする必要があるかによって異なります。それらが共通に持つ機能は何であれ、基本クラス、またはより適切と思われる場合はインターフェイスに配置する必要があります。

于 2008-10-22T20:43:32.803 に答える
1

あなたの最良の選択肢は、あなたが提案したように、インターフェースISomeClassを作成して実装することです。私は最近、さまざまなデータ型を保存するために使用したいと考えていたユーザー設定とプロファイル システムで、これとまったく同じ問題に取り組みました。それは次のようになりました:

public interface IEntry
{
    // ...
    object Value { get; set; }
}

暗黙的にインターフェイスを実装しているため、特定のEntry<Single>ものをインスタンス化できます。Entry<T>

public class Entry<T> : IEntry
{
    T Value { get; set; }
    object IEntry.Value { get { return Value; } set { return Value; } }
}

しかし、時が来たら、インスタンスを適切な型にキャストするか、Value プロパティを適切な型IDictionary<string,IEntry>にキャストすることに戻ります。IEntryEntry<T>IEntry

// assume entries is IDictionary<string,IEntry>...
var entry = entries["pizza-weight"];
var weight = (float)entry.Value;

もちろん、これは != と同じようにSomeClass<int>!=がSomeClass<long>真であるため、すべて意味があります。IList<SomeClass<int>>IList<SomeClass<long>>

于 2008-10-22T21:16:38.680 に答える