8

次のようなコレクション クラスがあります。

public class SomeDataCollection : List<ISomeData>
{
    // some method ...
}

しかし、私はこれを行うことはできません:

SomeDataCollection someDatas = new List<ISomeData>();

タイプを に暗黙的に変換することはできません。明示的な変換が存在します (キャストがありませんか?)List<ISomeData>SomeDataCollection

SomeDataCollectionだから私はコレクションクラス内に暗黙的な変換器を作成しようとします:

public static implicit operator SomeDataCollection(List<ISomeData> l)
{
    var someDatas = new SomeDataCollection();
    someDatas.AddRange(l);
    return someDatas;
}

しかし、私はそのようなコンバーターを作成できないと言っていました:

SomeDataCollection.implicit operator SomeDataCollection(List<ISomeData>):基本クラスとの間のユーザー定義の変換は許可されていません

そして、私がこのようにキャストすると:

SomeDataCollection someDatas = (SomeDataCollection)new List<ISomeData>();

次のようなエラーがスローされます。

System.InvalidCastException:型 のオブジェクトを型 にキャストできませList<ISomeData>SomeDataCollection

これどうやってするの:

SomeDataCollection someDatas = new List<ISomeData>();

エラーが発生しませんか?助けてください。前もって感謝します。

4

4 に答える 4

6

Anew List<ISomeData>();はまだただのList<ISomeData>. ではありませんSomeDataCollection。サブクラス化のポイントは、サブクラスが追加の状態などを持つことができるということですが、オブジェクトは (一度作成されると)決して型を変更しません。

同じ階層内のタイプ間で演算子を作成することは許可されていません。これは、通常の期待されるキャスト動作を覆すためです。

簡単に使用できます:

var data = new SomeDataCollection();

ただし、率直に言って、サブクラス化に役立つことはめったにないことを付け加えておく必要がありList<T>ます。特に、有用なメソッドが公開されていないvirtualため、動作を微調整することはできません。明確で実証可能な目的がない限り、私は正直に a を使用するList<ISomeData>(そして完全に削除する) だけです。SomeDataCollection次に、リストをカプセル化するか、から継承しCollection<T>ます。

メソッドを拡張メソッドとしていつでも追加できますか?

public static class Utils {
    public static void SomeMethod(this IList<ISomeData> list) {
      ...
    }
}

それから:

var list = new List<ISomeData>();
...
list.SomeMethod();
于 2012-06-27T07:46:58.327 に答える
2

にコンストラクタを実装した方がよいのではないSomeDataCollectionか?

public SomeDataCollection() : base() { }

これはもちろん、

public SomeDataCollection(IEnumerable<ISomeData> collection) 
    : base(collection) { }

SomeDataCollection次に、代わりに次のように初期化できるはずです。

SomeDataCollection someData = new SomeDataCollection();
SomeDataCollection someOtherData = 
    new SomeDataCollection(collectionOfSomeData);

のすべてのパブリック メソッドとプロパティに引き続きアクセスできますList<ISomeData>

于 2012-06-27T07:47:38.547 に答える
2

まず、なぜnew List<ISomeData>として定義された変数に書き込みたいのSomeDataCollectionですか? あなたが本当にしたかった可能性がありますSomeDataCollection someDatas = new SomeDataCollection();

エラーメッセージに関しては、最初のエラーメッセージは がList<ISomeData>から派生しSomeDataCollectionていないことを示しているため、 で行うようなことはできませんSomeDataCollection。したがって、次のように定義されている変数に書き込むことはできSomeDataCollectionませSomeDataCollectionpublic void someMethod()その中で、そして後であなたが呼び出すコードでsomeDatas.someMethod())。

2 番目のエラー メッセージは、コンバーターが、ベース型と派生型の間ではなく、完全に異なる型間の変換を目的としていることを示しています。それ以外の場合、たとえば次の例では、何が得られると予想されますか:

SomeDataCollection a = new SomeDataCollection();
List<ISomeData> b = (List<ISomeData>)a;
SomeDataCollection c = (SomeDataCollection)b;

コンバーターを呼び出す必要がありますか?

基本的に、あなたが書こうとしているコードは、最初から非常に間違っているので、あなたが何をしようとしているのかを知る必要があります。そうすれば、根本的な問題の解決策 (問題の解決策ではなく) を伝えることができるかもしれません。 「このコードをコンパイルする方法」)。

于 2012-06-27T07:42:36.147 に答える
0

ジェネリックでも問題ありません。C# では、基本クラスを派生クラスに明示的に変換することはできません。

于 2012-06-27T07:51:38.487 に答える