我很困惑。我偶然发现了签名规则(B.Liskov在她的作品中也提到过),该规则指出:
自变量的一致性。 m1 和 m2 的数量相同 论点。如果 m1 的参数类型列表是 a ,而 m2 的参数类型列表 是 b ,然后是∀i。 a i < b i //表示 a 是 b 。
从另一本教材中:
对于功能类型DY→CY为(可替代)的子类型 DX→CX,我们必须在结果类型中是协变的,但在结果类型中是协变的 参数类型!
那么这是否意味着如果我仅使用相同类型的参数和返回类型,就永远不会进行正确的子类型化吗?我不明白使用相同类型是否也很重要,即当我对父类和子类方法参数都使用相同类型时,这是变量吗?
换句话说,由于c#不允许参数互变,是否意味着我的代码从不符合LSP?正如我读到的,LSP要求参数必须是互变的。
class Person
{
}
class Employee: Person
{
}
class PersonRegister
{
GetJobTitle(Employee e) {return e.JobTitle;}
}
class DeriverRegister: PersonRegister
{
GetJobTitle(Person p) //contravariance, using less derived type, cannot be done in C#
}
如果例如较少派生的类型没有必填字段,在此示例中为JobTitle?那是雇员的财产,但必然是人的财产。
答案 0 :(得分:0)
class Person
{
}
class Employee: Person
{
}
class PersonRegister
{
GetJobTitle(Employee e) {return e.JobTitle;}
}
class DeriverRegister: PersonRegister
{
GetJobTitle(Person p) //contravariance, using less derived type, cannot be done in C#
}
您是正确的。如果您希望将GetJobTitle
中的DervierRegister
中的override
视为GetJobTitle
中PersonRegister
的{{1}},则它必须使用完全相同的 类型。应该允许以书面形式创建此方法,但是它会遮盖来自PersonRegister
的那个方法,并且不应将其视为替代。因此,您可以编写以上内容,但是
var e = new Employee();
PersonRegister pr = new DervierRegister();
pr.GetJobTitle(e);
将从PersonRegister
调用该方法。
这是否意味着我的代码从不符合LSP?
在无法普遍使用协方差和对数的情况下,是的。但是,对于通用interfaces and delegates,在C#4.0中添加了支持。而且,正如讨论的那样,当正式讲话时,每种类型都被视为自身的子类型,因此诸如“ a 是 a 的子类型”之类的短语对所有类型均成立< em> a 。