Array
类实现具有IList
成员的Add
接口。 Array.Add
调用会引发NotSupportedException
。是否违反 Liskov替代原则或接口隔离原则或两者都有?
答案 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);
}
}