6

私は一般的な分散について少し読んでいて、それを完全には理解していませんが、それが次のようなことを可能にするかどうか知りたいですか?

class A<T> { }

class B { }

class C : B { }

class My1  {
    public My1(A<B> lessDerivedTemplateParameter)
    {
    }
}

class My2 : My1 {
    public My2(A<C> moreDerivedTemplateParameter)
        : base(moreDerivedTemplateParameter) // <-- compile error here, cannot convert
    {
    }
}
4

2 に答える 2

6

いいえ、からC継承しますがB、からA<C>継承しないためA<B>です。

これが事実である理由を理解するために、A<T>代わりにそうであったかどうか想像してくださいList<T>

class B { }

class C : B { }

class D : B { }

class My1  {
    public My1(List<B> lessDerivedTemplateParameter)
    {
       // This is totally legal
       lessDerivedTemplateParameter.Add(new D());
    }
}

class My2 : My1 {
    public My2(List<C> moreDerivedTemplateParameter)
        // if this were allowed, then My1 could add a D to a list of Bs
        : base(moreDerivedTemplateParameter)
    {
    }
}

一方、これは合法です。

interface IA<out T> { 
    public T GetSome();
}

class B { }

class C : B { }

class D : B { }

class My1  {
    public My1(IA<B> lessDerivedTemplateParameter)
    {
       // This is totally legal
       var someB = lessDerivedTemplateParameter.GetSome();
    }
}

class My2 : My1 {
    public My2(IA<C> moreDerivedTemplateParameter)
        // This is allowed, because an A<C> only *produces* C's (which are also B's)
        // so the base class (which consumes B's, and doesnt care if they are C's) 
        // can use an IA<C>
        : base(moreDerivedTemplateParameter)
    {
    }
}
于 2012-05-25T19:17:53.720 に答える
2

Aを反変型パラメーターを持つインターフェースとして宣言すると、次のようにコンパイルされます。

internal interface A<out T>
    {
    }

    internal class B
    {
    }

    internal class C : B
    {
    }

    internal class My1
    {
    public My1(A<B> lessDerivedTemplateParameter)
    {
    }
}

internal class My2 : My1
{
    public My2(A<C> moreDerivedTemplateParameter)
        : base(moreDerivedTemplateParameter) 
    {
    }

}
于 2012-05-25T19:26:49.960 に答える