尝试应用里氏替换原理的 C# 编译错误

标签 c# .net solid-principles liskov-substitution-principle solid

我正在读一本关于设计模式的书,其中有关于里氏替换原则的一章,其中提到要做到这一点(以及其他任务)来实现该原则:

Parameter types in a method of a subclass should match or be more abstract than parameter types in the method of the superclass. Sounds confusing? Let’s have an example.

Say there’s a class with a method that’s supposed to feed cats: feed(Cat c).
Client code always passes cat objects into this method.

◦ Good: Say you created a subclass that overrode the method so that it can feed any animal (a superclass of cats): feed(Animal c). Now if you pass an object of this subclass instead of an object of the superclass to the client code, everything would still work fine. The method can feed all animals, so it can still feed any cat passed by the client.

◦ Bad: You created another subclass and restricted the feed- ing method to only accept Bengal cats (a subclass of cats): feed(BengalCat c). What will happen to the client code if you link it with an object like this instead of with the orig- inal class? Since the method can only feed a specific breed of cats, it won’t serve generic cats passed by the client, breaking all related functionality.

对我来说一切似乎都很好,直到我决定尝试用 C# 实现这个示例。
这是我为了更好地理解示例的“好”部分而编写的代码:

public class Animal { }
public class Cat : Animal { }


public class AnimalFeeder
{
    public virtual void Feed(Cat c)
    {
        Console.WriteLine("Feeding a cat...");
    }
}

public class GenericFeeder : AnimalFeeder
{
    public override void Feed(Animal a) // Compile Error - No suitable method found to override 
    {
        Console.WriteLine("Feeding an animal...");
    }
}

唯一的问题是我收到上面的错误,
也许我误解了这个例子,没有写出正确的代码,
如果是,有人可以帮助我以正确的方式更正代码吗?

提前谢谢您!

最佳答案

据我了解,里氏替换原则适用于单个继承层次结构。 “好”示例混合了两种类型层次结构,听起来更像逆变解释(如果替换superclass <-> interfacesubclass <-> 实现)

public class Program
{
    public static void Main()
    {
        var c = new Cat();
        IFeeder<Cat> f;
        
        f = new CatFeeder();    
        f.Feed(c);
        
        f = new GenericFeeder();    
        f.Feed(c);
    }
    
    public class Animal { }
    public class Cat : Animal { }
    
    public interface IFeeder <in T>
    { 
        void Feed(T x);
    }

    public class CatFeeder : IFeeder <Cat>
    {
        public void Feed(Cat c)
        {
            Console.WriteLine("Feeding a cat...");
        }
    }

    public class GenericFeeder : IFeeder <Animal>
    {
        public void Feed(Animal a)
        {
            Console.WriteLine("Feeding an animal...");
        }
    }
}

关于尝试应用里氏替换原理的 C# 编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75848348/

相关文章:

java - 澄清对 "Dependency Inversion"的理解

C# 跨网页保存 cookie 和 session

c# - C# 中的等效 C 代码。 (uint8_t *) 强制转换?

c# - 在 MVC 上执行编辑时如何保留某些字段的原始值?

c# - 将值四舍五入为 C# 中特定值的列表

c# - 当需要设计模块化架构时,对象转换是现实的必然吗?

c# - Entity Framework : How to update child data in foreach loop

c# - 将 IList<string> 转换为 IList<object> 在运行时失败

c# - C# 中多个表的联合

c# - 寻找一种设计模式来管理需要更新多个数据源中的数据的操作