c# - 了解 Liskov 替换原则

标签 c# solid-principles

我试图通过反复阅读 wikipedia 来确定我对上述原则的理解。条目。

抛开仍然让我感到悲伤的协变和逆变的概念,维基百科还提到父类(super class)型的不变量必须保留在子类型和历史约束或历史规则中。基于这最后两个概念,我想出了这个小例子:

class Program
{
    static void Main(string[] args)
    {
        var fooUser = new FooUser();

        var fooBase = new FooBase("Serge");

        var fooDerived = new FooDerived("Serge");

        fooUser.Use(fooBase); //will print "Serge"
        fooUser.Use(fooDerived); //will print "New User"

        Console.ReadKey();
    }
}

public class FooUser
{
    public void Use(IFoo foo)
    {
        foo.DoSomething();
        Console.WriteLine(foo.Name);
    }
}

public interface IFoo
{
    string Name { get; }
    void DoSomething();
}

public class FooBase : IFoo
{
    public string Name { get; protected set; }

    public FooBase(string name)
    {
        Name = name;
    }

    public virtual void DoSomething()
    {
    }
}

public class FooDerived : FooBase
{
    public FooDerived(string name) : base(name)
    {
    }

    public override void DoSomething()
    {
        Name = "New Name";

        base.DoSomething();
    }
}

所以我的问题是:基于上面提到的两个概念,我这个例子是否违反了原则?如果不是,为什么?

非常感谢您。

最佳答案

要违反 LSP,您需要一个对类接口(interface)做出一些假设的客户端类。假设不能完全以正式的方式表达,有时它只是来自使用的上下文。

假设您有一个允许您添加元素的可枚举类。例如,客户端的假设可以是,如果它添加 N 个元素,则可以从集合中读取恰好 N 个元素。然后你从你的集合中派生一个集合,它在添加时删除重复的元素。现在客户的期望是错误的,因为即使添加了 N 个元素,有时也可以读取不到 N 个元素。

然后对我来说,违反 LSP 需要一个定义一些期望的上下文。由于您的代码中没有期望,因此没有违反 LSP。

这种对上下文的需求也意味着两个类可以违反一个客户端上下文的 LSP,而相同的类可能不会违反其他上下文中的 LSP。

关于c# - 了解 Liskov 替换原则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11472962/

相关文章:

c# - Windows 窗体数据绑定(bind)

solid-principles - 到底是谁的责任呢?

c# - 如何在 .net 中使用 async/await 链接方法

c# - Google 建议文本框(自动完成)

c# - Unity Container - 具有通用工作统一性的多个数据库

c# - 非静态类中的私有(private)静态字段

java - 实现依赖注入(inject)设计模式

c# - 获取嵌套调用方法中的父方法参数值

c# - Winforms:平滑面板的圆角边缘

c# - 如何在 IEnumerable<T> 上实现 ICollection<T>