4

これを投稿する前に、合理的と思われる限り、検索して読んだり勉強したりしました。同様の質問を見つけましたが、ほとんどの投稿は実際には、 「基本型のリスト」を必要とする関数呼び出しに「派生型のリスト」を渡すことに関連しています。動物の例に感謝することができ、勉強した後はよりよく理解できたように感じます.

そうは言っても、特定のユースケースで解決する方法はまだわかりません。コレクション内の「TestInterface の GenericClass」のインスタンスを集約する必要があります。タスクを達成するための最善の方法と思われるものについて、最善の努力の下にコピーして貼り付けました。

namespace Covariance
{
    class Program
    {

        protected static ISet<GenericClass<TestInterface>> set = new HashSet<GenericClass<TestInterface>>();

        static void Main(string[] args)
        {
            set.Add(new GenericClass<A>());
            set.Add(new GenericClass<B>());
        }
    }

    class GenericClass<TemplateClass> where TemplateClass : TestInterface
    {
        TemplateClass goo;
    }

    public interface TestInterface
    {
        void test();
    }
    public class A : TestInterface
    {
        public void test()
        {
        }
    }

    class B : A
    {
    }
}

上記のコードは、次のコンパイル エラーで失敗します。

エラー CS1503: 引数 1: 'Covariance.GenericClass' から 'Covariance.GenericClass' に変換できません

エラー CS1503: 引数 1: 'Covariance.GenericClass' から 'Covariance.GenericClass' に変換できません

ヘルプ/ガイダンスまたは関連リンクは大歓迎です。繰り返しますが、これが重複した質問である場合はお詫び申し上げます。ありがとう!

4

1 に答える 1

4

バリアンス修飾子 (in、out) は、型ではなく、ジェネリック インターフェイスでのみ宣言できます。GenericClassしたがって、この問題を解決する 1 つの方法は、次のようにのインターフェイスを宣言することです。

interface IGenericClass<out TemplateClass> where TemplateClass : TestInterface {
    TemplateClass goo { get; }
}
class GenericClass<TemplateClass> : IGenericClass<TemplateClass> where TemplateClass : TestInterface
{
    public TemplateClass goo { get; }
}

その後

class Program {
    protected static ISet<IGenericClass<TestInterface>> set = new HashSet<IGenericClass<TestInterface>>();

    static void Main(string[] args) {
        set.Add(new GenericClass<A>());
        set.Add(new GenericClass<B>());
    }
}
于 2016-11-23T08:17:31.817 に答える