C#4.0方差可以帮我调用一个带有upcast的基类构造函数吗?

Aar*_*ide 6 c# generic-variance

我正在阅读关于泛型方差的一些内容,但我还没有完全理解它,但我想知道它是否可能产生类似下面的内容?

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
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*ain 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)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

另一方面,这是合法的:

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)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)