Skip to content

Break in Liskov's Substitution Principle

Dima Enns edited this page Jul 9, 2020 · 2 revisions

The collections from this project do implement the IList interface (see API Documentation). However, they don't support most of the interfaces functions besides the indexer and the Count property. That is a heavy break in Liskov Substitution Principle. Hence, these collections cannot be used like full-fledged IList implementation. But this principle break is on purpose. Let's take the function Contains, for example. How should be checked if the data represented by this collection contains the searched element? Sure, you could check the already loaded pages. But what if you are not lucky? What if the collection doesn't even contain the element. The consequence would be to load all remaining elements in order to check for the searched element. This would contradict the initial purpose of the data virtualization and eliminate its advantages. And besides that, usually a data virtualizing solution is used in combination with databases, hence such a "Contains"-request is better of as a query applied directly to the database.

Collection-mutating functions like Add and Remove aren't supported as well, because the data virtualizing collections here are read only.

Why is implementing IList necessary?

Short answer: In order to support data virtualizing for ItemsControls on the ItemsSource-property in WPF we need are required to use IList.

ICollection doesn't provide an indexer. Consequently, controls which get an ICollection need to iterate over 999,999 elements - whether they are displayed or not - in order to show the 1,000,000th element. That compromises the data virtualization, because potentially a lot of elements have to be loaded which are not needed. If the controls know that they are working with an IList then they can optimize utilizing the indexer and just retrieve the millionth element directly. But why not just use IReadOnlyList<T>? Conceptually IReadOnlyList<T> would be perfect. The LSP wouldn't be broken and we would have an indexer. However, WPF controls cannot use generic collection interfaces, because WPF is compiled without including your application and therefore cannot reference your chosen type for T. Unfortunately there is no non-generic variant of IReadOnlyList<T> in .Net Framework or .Net Core. These circumstances leave IList as only option.

Clone this wiki locally