逆变和协变是否意味着也使用相同的类型?

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 被视为来自 PersonRegisterGetJobTitleoverride,则必须使用 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.