【发布时间】:2016-06-19 08:48:45
【问题描述】:
我刚刚安装了 Microsoft 代码合同。它是 .NET Framework 和 Visual Studio 插件的一部分。它提供对已定义合约的运行时检查和静态检查。
该工具有四个警告级别,所以我设置了最高。
我已经声明了旨在违反 Liskov 替换原则的类。
public class Person
{
protected int Age { get; set; }
public Person(int age)
{
Contract.Requires(age > 0);
Contract.Requires(age < 130);
this.Age = age;
}
}
public class Child : Person
{
public Child(int age) : base(age)
{
Contract.Requires(age > 0);
Contract.Requires(age < Consts.AgeOfMajority);
Contract.Requires(age < 130);
this.Age = age;
}
}
public static class Consts
{
public readonly static int AgeOfMajority = 18;
}
LSP 状态:
如果 S 是 T 的子类型,则 T 类型的对象可以替换为 类型 S 的对象,而不改变任何所需的属性 那个程序
在我的示例中,违规将是这个分配:Person person = new Child(23);。我们应该能够做到这一点,但我们做不到,因为孩子的年龄不能超过 person 类要求的年龄。
然而,分析结果令人惊讶CodeContracts: Checked 11 assertions: 11 correct。我的示例是错误的还是代码合同没有检测到此类事情?
【问题讨论】:
-
我不认为这违反了 LSP 的现状。您的课程没有任何行为,并且它们具有相同的 api。唯一的区别是它们的构造规则不同,但我解释 LSP 的方式是从使用该类的客户端的角度来看的。任何与
Persons打交道的人都不应该知道关于孩子最大年龄的规则。在这种情况下,他们不必这样做。 -
请注意,setter 是不受限制的。修复它,你应该得到一个错误。
-
@Kevin 我已经实现了 full age 属性并添加了 requires 语句。仍然没有警告。
标签: c# code-contracts solid-principles liskov-substitution-principle