Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, artelk, Вы писали:
A>>А пример приведи, плиз.
Z>Z>if (x.GetType() == typeof(SomeConcreteType))
Z>{
Z> //...
Z>}
Z>
У типов и у функций есть контракты. По сути это некие ограничения, накладываемые на них. Часть из них выражается явно и может быть проверена компилятором. Часть — не может быть выражена в рамках используемого языка программирования.
Для примера возьмем C#.
Если под контрактом типа подразумевать только набор сигнатур его методов и игнорировать эту неявную составляющую контракта, то любое наследование автоматом станет удовлетворять LSP и никакого смысла в этом принципе не будет.
В контракт функции входит, в частности, ее имя, типы ее параметров и тип возвращаемого значения. Проверка на соответствие передаваемых ей параметров ее контракту осуществляется статически на этапе компиляции.
class SomeBaseType
{...}
class SomeConcreteType: SomeBaseType
{...}
class SomeConcreteType2: SomeBaseType
{...}
void SomeFunc(SomeBaseType x)
{
//...
((SomeConcreteType)x).SomeMethod();
//...
}
Вопрос: что является контрактом этой функции и правильно ли он выражен синтаксически?
При передаче ей SomeConcreteType2 будет выброшен InvalidCastException.
Если считать это ожидаемым поведением функции SomeFunc, то нарушения LSP нет.
Если считать это ошибочным поведением, то контракт функции указан некорректно — ее параметр должен иметь тип SomeConcreteType. Просто проверка компилятором была подавлена.
class SomeConcreteType3: SomeBaseType
{...}
void SomeFunc(SomeBaseType x)
{
//...
if(x is SomeConcreteType)
{
((SomeConcreteType)x).SomeMethod();
}
else
{
((SomeConcreteType2)x).SomeMethodOfType2();
}
//...
}
Тут контрактом на параметр будет, что он не null и имеет тип SomeConcreteType
или SomeConcreteType2. Такое условие невыразимо на C#, т.е. это неявный контракт.
Еще пример с неявным контрактом:
interface ISort<T>
where T: IComparable<T>
{
T[] Sort(IEnumerable<T> items);
}
class BadSort: ISort<int>
{
int[] Sort(IEnumerable<int> items) { return items.ToArray(); }
}
Тут BadSort противоречит неявному контракту — он не делает сортировку.
В каких-то языках можно больше выразить явно, в каких-то меньше. В языках с зависимыми типами, например, можно даже требование сортировки выразить явно и BadSort вообще не скомпилируется...