尝试应用里氏替换原理的 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/

相关文章:

oop - 里氏替换原理的例子是什么?

java - 没有反射是否可以确定要运行的类

c# - 在使用对象时从一种实现类型转换为另一种实现类型是否合适?

c# - GridView 数据绑定(bind)

C# mongo 附近查询无法找到 $geoNear 的索引

c# - 用于创建 lambda 以生成 C# 字典的表达式树

.net - 如何在 MVC 4 中使用 NHaml?

c# - Google Protocol Buffers - protobuf-net 反序列化无法正常工作

c# - 使用 P/Invoke Interop Assistant 时的数据结构和堆栈损坏

c# - 为什么 (int)==(float) 总是编译为 (float)==(float)