C#返回类型协方差和Liskov替换原理
我正在尝试理解协方差和LSP。 从这个问题我可以看出C#不支持返回类型协方差。 然而Liskov替换原则对返回类型强加协方差。
这是否意味着在C#中应用这个原则是不可能的? 还是我想念一些东西?
C#仍然可以应用Liskov替换原则。
考虑:
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(); } }
如果C#支持协变返回类型,那么Base2
Method()
的覆盖可以这样声明:
public class Derived2 : Base2 { public override Derived1 Method() { return new Derived1(); } }
C#不允许这样做,并且必须声明返回类型与基类中的返回类型相同,即Base1
。
但是,这样做并不违反Liskov替代原则。
考虑一下:
Base2 test = new Base2(); Base1 item = test.Method();
相比:
Base2 test = new Derived2(); Base1 item = test.Method();
我们完全能够用new Derived2()
替换new Base2()
new Derived2()
而没有任何问题。 这符合Liskov替代原则。
由于C#不支持返回类型协方差,因此在返回类型协方差时不可能违反Liskov原则。
好的消息来源是关于C#中SOLID原则的讨论: https : //youtu.be/gwIS9cZlrhk?t = 1886
C#通过generics和out
generics修饰符确实对此function提供了有限的支持。 (参见: https : //docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-generic-modifier )
支持是有限的,因为它只适用于接口。 要重写接受的答案:
public class Base1 { } public class Derived1 : Base1 { } public interface Base2 where T : Base1 { T Method(); } public class Derived2 : Base2 { public Derived1 Method() { return new Derived1(); } }
在这种情况下, Derived2
不仅会实现Base2
,还会实现Base2
。
该原则生效,因为如果通过Base2
接口调用Method
,它将具有Base1
返回类型,但如果通过Derived2
调用它,则它将具有Derived1
返回类型。
类似地,您可以使用in
generic修饰符实现参数逆转: https : //docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-generic-modifier
注意,不可能违反原则。 如果在上面的示例中将out
关键字更改为in
关键字,则源代码将无法编译,您将收到以下错误:
上述就是C#学习教程:C#返回类型协方差和Liskov替换原理分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
Error CS1961 Invalid variance: The type parameter 'T' must be covariantly valid on 'Base2.Method()'. 'T' is contravariant.
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/942708.html