System.String нарушает Liskov substitution principle?
От: igna Россия  
Дата: 13.07.07 15:47
Оценка: :)
В Википедии дано такое определение LSP:

Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.


Не знаю можно ли здесь q(x) заменить на q(x1, x2), но если можно, и в случае соблюдения LSP верно следуюшее:

Let q(x1, x2) be a property provable about objects x1 and x2 of type T. Then q(y1, y2) should be true for objects y1 and y2 of type S where S is a subtype of T.


, то в .NET наследование System.String от System.Object нарушает LSP, потому как

Object.ReferenceEquals(x1, x2) || !x1.Equals(x2)

всегда верно для x1 и x2 являюшихся Object, но

Object.ReferenceEquals(y1, y2) || !y1.Equals(y2)

не верно в общем случае для y1 и y2 являющихся String.
Re: System.String нарушает Liskov substitution principle?
От: mkizub Литва http://symade.tigris.org
Дата: 13.07.07 16:45
Оценка:
Здравствуйте, igna, Вы писали:

[бред поскипан]

Вы бы попробовали понять об чём этот LSP, а не подходить к нему формально, да ещё с произвольными изменениями.
В таком формальном подходе LSP вообще невозможен, так как при наследовании как минимум меняется класс объекта, даже если ничего не добавлено и не переопределено.
Понятно? А теперь думайте, что же на самом деле означает LSP.
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[2]: System.String нарушает Liskov substitution principle?
От: igna Россия  
Дата: 13.07.07 17:10
Оценка:
Здравствуйте, mkizub, Вы писали:

M>Вы бы попробовали понять об чём этот LSP...


Беру пример отсюда (C++):

void g(Rectangle& r)
{
    r.SetWidth(5);
    r.SetHeight(4);
    assert(r.GetWidth() * r.GetHeight()) == 20);
}


Пример этот приведен (на 5-ой странице), чтобы показать, почему Square нельзя производить от Rectangle.

По аналогии пишу (C#):

void f(Object x1, Object x2)
{
    Debug.Assert(Object.ReferenceEquals(x1, x2) || !x1.Equals(x2));
}
Re: System.String нарушает Liskov substitution principle?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 13.07.07 17:38
Оценка: 1 (1)
Здравствуйте, igna, Вы писали:

I>не верно в общем случае для y1 и y2 являющихся String.


А я всегда говорил: такое наследование — фтопку.
Рулят полиморфные типы (ака генерики), интерфейсы, ну и в крайнем случае наследование от абстрактных классов.
Re: System.String нарушает Liskov substitution principle?
От: deniok Россия  
Дата: 13.07.07 18:07
Оценка: 2 (2)
Здравствуйте, igna, Вы писали:

I>В Википедии дано такое определение LSP:


I>

I>Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.


[skiped]

Это всё не то.

Смысл в том, что любые семантические контракты T, используемые при написания полиморфного кода, использующего T, должны при наследовании сохраняться.

class My
{
protected:
    int data;  
    ...
public:
    virtual void Reset(); // Декларировано, что Reset выставляет data в 0. (Задан семантический контракт)
    ...

}

// полиморфная функция
void doSomething (My& my)
{
   ...
   my.Reset();
   ... // код, полагающийся на семантический контракт data == 0
}


Любой наследник My при перегрузке Reset() должен поддерживать семантический контракт (выставлять data в ноль), иначе поведение doSomething будет неверным
class MyChild : public My
{
   virtual void Reset(){data = 1;} // Опс! При перегрузке нарушили контракт.
}

void foo()
{
   MyChild x;
   doSomething(x); // Бац! Прострелили ногу...
}
Re[3]: System.String нарушает Liskov substitution principle?
От: mkizub Литва http://symade.tigris.org
Дата: 13.07.07 18:13
Оценка: 1 (1) +1
Здравствуйте, igna, Вы писали:

M>>Вы бы попробовали понять об чём этот LSP...


I>Беру пример отсюда (C++):


Да не пример брать надо. Думать надо.

obj.GetType()


уже нарушается при любом наследовании. Это что, значит ОО не соответствует LSP?
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re: System.String нарушает Liskov substitution principle?
От: Hobot Bobot США  
Дата: 13.07.07 19:11
Оценка:
Здравствуйте, igna, Вы писали:

I>В Википедии дано такое определение LSP:


I>

I>Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.


Вы немного неправильно перевели фразу. "Should be true" в данном случае означает "должно быть правильным (осмысленным)" а не "должно возвращать true".
What a piece of work is a man! how noble in reason! how infinite in faculty! in form and moving how express and admirable! in action how like an angel! in apprehension how like a god! the beauty of the world! the paragon of animals!
Re: System.String нарушает Liskov substitution principle?
От: Константин Б. Россия  
Дата: 14.07.07 03:21
Оценка: 1 (1) -1
Здравствуйте, igna, Вы писали:

I>В Википедии дано такое определение LSP:


I>

I>Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.


I>Не знаю можно ли здесь q(x) заменить на q(x1, x2), но если можно, и в случае соблюдения LSP верно следуюшее:


I>

I>Let q(x1, x2) be a property provable about objects x1 and x2 of type T. Then q(y1, y2) should be true for objects y1 and y2 of type S where S is a subtype of T.


I>, то в .NET наследование System.String от System.Object нарушает LSP, потому как


I>
I>Object.ReferenceEquals(x1, x2) || !x1.Equals(x2)
I>

I>всегда верно для x1 и x2 являюшихся Object, но

I>
I>Object.ReferenceEquals(y1, y2) || !y1.Equals(y2)
I>

I>не верно в общем случае для y1 и y2 являющихся String.

А попроще пример нашел:

!(x is string)

Всегда верное если x — Object и не верно для x являющимся String.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: System.String нарушает Liskov substitution principle?
От: cvetkov  
Дата: 14.07.07 12:23
Оценка:
Здравствуйте, igna, Вы писали:

I>В Википедии дано такое определение LSP:


I>

I>Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.


I>Не знаю можно ли здесь q(x) заменить на q(x1, x2), но если можно, и в случае соблюдения LSP верно следуюшее:


I>

I>Let q(x1, x2) be a property provable about objects x1 and x2 of type T. Then q(y1, y2) should be true for objects y1 and y2 of type S where S is a subtype of T.


I>, то в .NET наследование System.String от System.Object нарушает LSP, потому как


I>
I>Object.ReferenceEquals(x1, x2) || !x1.Equals(x2)
I>

I>всегда верно для x1 и x2 являюшихся Object, но

I>
I>Object.ReferenceEquals(y1, y2) || !y1.Equals(y2)
I>

I>не верно в общем случае для y1 и y2 являющихся String.
И что из этого следует?
И почему только string? Любой класс в котором перегружено Equals его тоже нпрушает, иначе небыло бы смысла его перегружать.
Re[2]: System.String нарушает Liskov substitution principle?
От: IDL  
Дата: 14.07.07 16:49
Оценка:
Здравствуйте, nikov, Вы писали:

N>Здравствуйте, igna, Вы писали:


I>>не верно в общем случае для y1 и y2 являющихся String.


N>А я всегда говорил: такое наследование — фтопку.

А какое наследование не фтопку, кроме ниже описанных

N>Рулят полиморфные типы (ака генерики), интерфейсы, ну и в крайнем случае наследование от абстрактных классов.
Re: :shuffle:
От: igna Россия  
Дата: 14.07.07 18:50
Оценка:
Признаю, что спросил глупость.

Конечно же не любое утверждение "provable about objects x of type T" "should be true for objects y of type S where S is a subtype of T".

Прошу принять во внимание пятницу, 13-е, а также конец дня и вообще недели.
Re: System.String нарушает Liskov substitution principle?
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.07 12:04
Оценка: 3 (2)
Здравствуйте, igna, Вы писали:
I>не верно в общем случае для y1 и y2 являющихся String.
Это также неверно в общем случае для y1 и y2, являющихся object. Поскольку вначале была сделана неверная посылка (предложенное свойство не является доказуемым), то и вывод неверен.

Конкретно, ваша ошибка в том, что вы сузили тип T до точного object, выбросив из рассмотрения его подтипы. А этого делать нельзя. Все объекты, которые отвечают true на x is T, входят в этот тип. В частном случае System.Object реализацим Equals и ReferenceEquals совпадают. Но это не является частью контракта.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: System.String нарушает Liskov substitution principle?
От: Трурль  
Дата: 24.07.07 06:08
Оценка: +1
Здравствуйте, mkizub, Вы писали:


M>
M>obj.GetType()
M>


M>уже нарушается при любом наследовании. Это что, значит ОО не соответствует LSP?

Нет, это значит что obj.GetType() не соответсвует ОО.
Re[5]: System.String нарушает Liskov substitution principle?
От: mkizub Литва http://symade.tigris.org
Дата: 24.07.07 07:07
Оценка: +2
Здравствуйте, Трурль, Вы писали:

Т>Нет, это значит что obj.GetType() не соответсвует ОО.


Это у вас какая-то неизвестная науке ревизия OO, из которой начисто отрезали полиморфизм.
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[4]: System.String нарушает Liskov substitution principle?
От: . Великобритания  
Дата: 24.07.07 09:44
Оценка:
mkizub wrote:

> Да не пример брать надо. Думать надо.

>
> obj.GetType()
> уже нарушается при *любом* наследовании. Это что, значит ОО не
> соответствует LSP?
Может поэтому в некоторых языках используют более концептуально чистое typeof(obj)?
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: System.String нарушает Liskov substitution principle?
От: mkizub Литва http://symade.tigris.org
Дата: 24.07.07 13:22
Оценка:
Здравствуйте, ., Вы писали:

>> obj.GetType()

>> уже нарушается при *любом* наследовании. Это что, значит ОО не соответствует LSP?
.>Может поэтому в некоторых языках используют более концептуально чистое typeof(obj)?

А в чём разница? Принцип "нарушается" всё так же успешно.
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[5]: System.String нарушает Liskov substitution principle?
От: Трурль  
Дата: 24.07.07 13:54
Оценка:
Здравствуйте, ., Вы писали:

.>Может поэтому в некоторых языках используют более концептуально чистое typeof(obj)?

Концептуально чистое — это obj is T.
Re[6]: System.String нарушает Liskov substitution principle?
От: . Великобритания  
Дата: 24.07.07 15:22
Оценка:
Трурль wrote:

> .>Может поэтому в некоторых языках используют более концептуально чистое

> typeof(obj)?
> Концептуально чистое — это obj is T.
Ну это булева функция... и если тип является классом... есть рефлексия... скажем для такой записи:
Type t = typeof(obj)

но да... уже не чисто.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: System.String нарушает Liskov substitution principle?
От: Maxim S. Shatskih Россия  
Дата: 23.11.07 15:34
Оценка:
Т>>Нет, это значит что obj.GetType() не соответсвует ОО.

M>Это у вас какая-то неизвестная науке ревизия OO, из которой начисто отрезали полиморфизм.


.GetType — это не полиморфизм, а концептуально ему противоположная RTTI, а программирование с явным использованием RTTI действительно не соответствует ОО.

Это расширение ОО, в достаточно произвольную сторону.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[2]: System.String нарушает Liskov substitution principle?
От: Maxim S. Shatskih Россия  
Дата: 23.11.07 15:37
Оценка:
D>Смысл в том, что любые семантические контракты T, используемые при написания полиморфного кода, использующего T, должны при наследовании сохраняться.

И они тоже в приведенном примере не сохраняются. Object.Equals есть расширительно истолкованный Object.ReferenceEquals, а String.Equals не имеет никакого отношения к String.ReferenceEquals.

Как раз именно семантический контракт у Equals и не сохранен.
Занимайтесь LoveCraftом, а не WarCraftом!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.