Array.Add方法是否违反了LSP?

时间:2017-09-29 07:20:56

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

Array类实现具有IList成员的Add接口。 Array.Add调用会引发NotSupportedException。是否违反 Liskov替代原则接口隔离原则或两者都有?

2 个答案:

答案 0 :(得分:6)

这绝对违反了界面隔离原则。 ISP声明组件应该仅依赖于它们实际需要的接口。 Array实现IList,但显然不需要或不需要IList定义的所有方法,因为它选择抛出异常来解释它不支持Add }。此外,任何需要Array的东西现在都有IList,尽管不需要它的所有方法(因为任何想要数组的东西显然不会担心Add,因为它不起作用无论如何)。不支持您的界面建议您实施的操作显然是ISP违规;虽然不需要全部代码,但强制消费代码依赖于接口也是ISP违规。

可能导致违反Liskov替换原则。如果代码依赖于IList,则LSP声明在传递 IList的任何实现时它应该正常运行。但是,当传递Array时,该代码现在会在尝试调用Add时抛出异常。

这是否构成LSP违规取决于您如何看待LSP的异常。如果你从例外是预期合同的一部分的角度来看待它,那就没关系了。该方法符合其合同,任何调用Add而不考虑异常可能性的代码都是错误的。

如果你更认为NotSupportedException被认为是错误或失败,那么这是一个明显的LSP违规。就个人而言,我发现SOLID原则相互支持并且在真空中难以解决,因此使用接口隔离原则作为备份,我会说接口说“我可以做这些事情”,所以说“实际上,我不能做那件事“是一个错误,因此可能不应被视为有效合同的一部分。如果异常不是合同的一部分,那么抛出一个,Array违反了Add的合同,因此破坏了LSP。

答案 1 :(得分:0)

Liskov 替换原则 -

<块引用>

使用接口的程序不能被接口混淆 该接口的实现。

在实现 IList<> 的情况下,数组是一个例外 - 这是混淆的。

void Main() 
{ 
    var arr = new int[]{1,2,3}; 

    Test(arr);  
    
    void Test(IList<int> list)
    {
        list.Add(4);
    }
}