逆变和协变是否意味着也使用相同的类型?
Does contravariance and covariance means using also the same type?
我很困惑。我偶然发现了签名规则(在她的作品中也被 B.Liskov 引用),它声明:
Contravariance of arguments. m1 and m2 have the same number of
arguments. If the list of argument types of m1 is a, and that of m2
is b, then ∀i . ai < bi //meaning that a is subtype of b.
来自另一个教学material:
For a function type DY→CY to be a subtype of (I.e., substitutable for)
DX→CX , we must be covariant in the result type, but contravariant in
the argument type!
如果我只使用相同类型的参数和 return 类型,这是否意味着我永远不会进行正确的子类型化?我不明白使用相同类型是否也算数,即当我对父方法参数和子方法参数使用相同类型时 class,这是逆变吗?
换句话说,由于 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?那是 属性 的员工,但必然是个人的。
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#
}
你是对的。如果您希望 DervierRegister
中的 GetJobTitle
被视为来自 PersonRegister
的 GetJobTitle
的 override
,则必须使用 exactly相同的类型。你应该 allowed 来创建这个写的方法,但是它 shadows 来自 PersonRegister
的方法并且不被认为是覆盖.所以可以这样写,但是
var e = new Employee();
PersonRegister pr = new DervierRegister();
pr.GetJobTitle(e);
将从 PersonRegister
调用方法。
does it mean my code is never LSP compliant?
在某种程度上你不能使用协变和逆变通常,是的。但是,对于泛型 interfaces and delegates,在 C# 4.0 中添加了支持。而且,正如所讨论的,当正式说话时,每种类型都被认为是其自身的子类型,因此诸如“a is subtype of a”这样的短语适用于所有类型 a.
我很困惑。我偶然发现了签名规则(在她的作品中也被 B.Liskov 引用),它声明:
Contravariance of arguments. m1 and m2 have the same number of arguments. If the list of argument types of m1 is a, and that of m2 is b, then ∀i . ai < bi //meaning that a is subtype of b.
来自另一个教学material:
For a function type DY→CY to be a subtype of (I.e., substitutable for) DX→CX , we must be covariant in the result type, but contravariant in the argument type!
如果我只使用相同类型的参数和 return 类型,这是否意味着我永远不会进行正确的子类型化?我不明白使用相同类型是否也算数,即当我对父方法参数和子方法参数使用相同类型时 class,这是逆变吗?
换句话说,由于 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?那是 属性 的员工,但必然是个人的。
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#
}
你是对的。如果您希望 DervierRegister
中的 GetJobTitle
被视为来自 PersonRegister
的 GetJobTitle
的 override
,则必须使用 exactly相同的类型。你应该 allowed 来创建这个写的方法,但是它 shadows 来自 PersonRegister
的方法并且不被认为是覆盖.所以可以这样写,但是
var e = new Employee();
PersonRegister pr = new DervierRegister();
pr.GetJobTitle(e);
将从 PersonRegister
调用方法。
does it mean my code is never LSP compliant?
在某种程度上你不能使用协变和逆变通常,是的。但是,对于泛型 interfaces and delegates,在 C# 4.0 中添加了支持。而且,正如所讨论的,当正式说话时,每种类型都被认为是其自身的子类型,因此诸如“a is subtype of a”这样的短语适用于所有类型 a.