C # return type covariance and Liskov substitution principle

I am trying to understand Covariance and LSP. From this question, I see that C # does not support return type covariance. However, the Liskov substitution principle imposes covariance on the return type.

Does this mean that this principle cannot be applied in C #? Or am I not understanding something?

+4
source share
3 answers

C # can still apply the Liskov substitution principle.

Consider:

public class Base1
{
}

public class Derived1 : Base1
{
}

public class Base2
{
    public virtual Base1 Method()
    {
        return new Base1();
    }
}

public class Derived2 : Base2
{
    public override Base1 Method()
    {
        return new Derived1();
    }
}

If C # supports covariant return types, then an override for Method()in Base2can be declared as follows:

public class Derived2 : Base2
{
    public override Derived1 Method()
    {
        return new Derived1();
    }
}

# , , , Base1.

.

:

Base2 test = new Base2();
Base1 item = test.Method();

:

Base2 test = new Derived2();
Base1 item = test.Method();

new Base2() new Derived2() . .

+4
0

# generics out generic. (.: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-generic-modifier)

, . :

public class Base1
{
}

public class Derived1 : Base1
{
}

public interface Base2<out T> where T : Base1
{
    T Method();
}

public class Derived2 : Base2<Derived1>
{
    public Derived1 Method()
    {
        return new Derived1();
    }
}

Derived2 Base2<Derived1>, Base2<Base1>.

, , Method Base2<Base1>, Base1, Derived2, Derived1.

Similarly, you can implement parametric contravariance using the ingeneric modifier : https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-generic-modifier

Please note that it is not possible to violate the principle. If in the example above you change the keyword outto a keyword in, the source will not compile and you will receive the following error:

Error   CS1961  Invalid variance: The type parameter 'T' must be covariantly valid on 'Base2<T>.Method()'. 'T' is contravariant.
0
source

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


All Articles