Can C # 4.0 variance help me call base class constructor with raise?

I read a little about general variance and I don't have a full understanding yet, but I would like to know if this does something like the following:

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 { } } 
+6
source share
2 answers

No, because while C inherits from B , A<C> does not inherit from A<B> .

To understand why this is so, imagine if there were List<T> instead of 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) { } } 

Now, on the other hand, this is legal:

 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 (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) { } } 
+6
source

You can declare A as an interface with a parameter of contravariant type, and it will compile:

 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) { } } 
+2
source

Source: https://habr.com/ru/post/916698/


All Articles