3

ネストされたジェネリックコレクションを使用してデザインを実装しているときに、C#の不変ジェネリックによって明らかに引き起こされたこれらの制限に遭遇しました。

'Collection<Tのサブタイプ>から'Collection<T>'に変換できません

つまり、明らかにジェネリックスの不変性のために、以下は機能しません。

class Outer<TInner, TInnerItem> where TInner : Inner<TInnerItem>
{
    public void Add(TInner item)
    {
        item.Outer = this; // ERROR:
            // Cannot implicitly convert from Outer<TInner, TInnerItem> 
            // to Outer<Inner<TInnerItem>, TInnerItem>
    }
}

class Inner<TInnerItem> : ICollection<TInnerItem>
{
    Outer<Inner<TInnerItem>, TInnerItem> _outer;

    public Outer<Inner<TInnerItem>, TInnerItem> Outer
    {
        set { _outer = value; }
    }
}

(実際のコードでは、との両方Inner<>Outer<>実装しICollection<>ます。)

Inner<>一部のデータにアクセスするには、オブジェクトにコンテナコレクションへの参照が必要です。

できれば上記の一般的なアプローチを使用して、これらのネストされたコレクションをどのように実装しますか?Inner<>クラス内のコンテナコレクションへの参照をどのように設定しますか?

乾杯!

4

2 に答える 2

2

TInnerに依存しない(おそらく抽象的な)基本クラスを導入すると、次のことが役立つ場合があります。

abstract class OuterBase<TInnerItem>
{
}

class Outer<TInner, TInnerItem> : OuterBase<TInnerItem> where TInner : Inner<TInnerItem>
{
    public void Add(TInner item)
    {
        item.Outer = this; // Compiles
    }
}

class Inner<TInnerItem> : ICollection<TInnerItem>
{
    OuterBase<TInnerItem> _outer;

    public OuterBase<TInnerItem> Outer
    {
        set { _outer = value; }
    }
}

または、co / contra-variantジェネリックインターフェイスを導入するC#4.0を待ちます。

于 2009-05-11T13:51:05.250 に答える
0

この言語では、Collection<Tのサブタイプ>からCollection<T>に変換することはできません。

その理由を説明させてください。

コレクション<subT>があり、それをコレクション<T>にキャストするとします。subTはTから継承するので、問題ありません。

からオブジェクトを取得するとcollection_of_T、問題がないことが保証されます。

後で、にTオブジェクトを追加しますcollection_of_T。これで、collection_of_subTではないオブジェクトにがありますsubT。おっと。

あなたが望むものを達成するために、あなたは一緒に新しいコレクションを作成しなければなりません。

Collection<T> collection_of_T = new Collection<T>(collection_of_subT);

これはおそらくあなたにとって良くありません。クラスTInnerで一般的な引数が本当に必要ですか?代わりに、コードの残りの部分でにOuter置き換えることは可能でしょうか?Inner<TInnerItem>

于 2009-05-11T15:22:18.440 に答える