質問

クラスPの型パラメーターTに<!> quot; A <!> quot;から継承する必要がある一般的な制約がある場合、最初の呼び出しは成功しますが、2番目の呼び出しは、コメント:

abstract class A { }

static class S
{
    public static void DoFirst(A argument) { }
    public static void DoSecond(ICollection<A> argument) { }
}

static class P<T>
    where T : A, new()
{
    static void Do()
    {
        S.DoFirst(new T());             // this call is OK

        S.DoSecond(new List<T>());      // this call won't compile with:

        /* cannot convert from 'System.Collections.Generic.List<T>'
           to 'System.Collections.Generic.ICollection<A>' */
    }
}

List<T> が実際にICollection<A>であることを一般的な制約で保証すべきではないか

役に立ちましたか?

解決

これは、C#にジェネリック型(C#配列の共分散をサポートします 。 C#4は、この機能をインターフェイスタイプに追加し、いくつかのBCLインターフェイスタイプも更新して同様にサポートします。

C#4.0:共分散と反分散

  

この記事では、I <!>#8217;カバーを試みます   C#4.0の革新。一つ   新機能は共分散であり、   型パラメーターの反分散   汎用デリゲートによってサポートされるようになりました   および汎用インターフェース。まずは<!>#8217; s   これらの単語の意味を確認してください:)

他のヒント

制約は問題に影響しません。問題は、ICollectionを必要とするパラメーターでリストを渡すことです。C#は共分散をサポートしていないため、リストを明示的にICollectionにキャストする必要があります。

S.DoSecond((ICollection<A>) new List<T>());      // this call will be happy

DoSecondのパラメーターをICollection <!> lt; A <!> gt;型として強く入力しました。 TはタイプAであるにもかかわらず、コンパイル時にList <!> lt; T <!> gt;の間に暗黙的キャストはありません。およびICollection <!> lt; A <!> gt;。リストを作成してICollection <!> lt; A <!> gt;にキャストする必要があります。 DoSecondを呼び出すとき、またはDoSecond自体をジェネリックメソッドにするとき。

注:このタイプの暗黙のキャストは、C#4.0でサポートされる必要があります。これにより、C#3.0が提供するものよりも大幅に改善された相互/共分散が提供されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top