Аннотация:
Данная статья посвящена вопросу грамотной реализации операторов сравнения. При кажущейся простоте, эта задача несет в себе ряд скрытых трудностей. Реализация операторов сравнения нередко приводит к появлению неприятных ошибок. В основном эта информация касается C#-программистов, но будет полезна тем, кто пишет .NET-код и на других языках.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
ЧВV>Авторы: ЧВV> Чистяков Влад (VladD2)
ЧВV>Аннотация: ЧВV>Данная статья посвящена вопросу грамотной реализации операторов сравнения. При кажущейся простоте, эта задача несет в себе ряд скрытых трудностей. Реализация операторов сравнения нередко приводит к появлению неприятных ошибок. В основном эта информация касается C#-программистов, но будет полезна тем, кто пишет .NET-код и на других языках.
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, Чистяков Влад (VladD2), Вы писали:
V>Кстати, меня весьма раздражает тот факт, что если я переопределил операторы == и !=, то простая проверка: V>
V>if(myObj!=null)
V>
V>приводит к вызову кучи кода, вместо того, чтобы просто заэммитить в байткод проверку на null.
Вызывай
!object.ReferenceEquals(myObj, null)
А то ты хочешь странного: я переопределил оператор, но не хочу что бы он переопределялся.
Здравствуйте, vdimas, Вы писали:
_>>А то ты хочешь странного: я переопределил оператор, но не хочу что бы он переопределялся. V>Что-то я не понял рассуждения, ты хочешь сказать, что может быть еще какая-то семантика проверки ссылочного типа на null?
Неоднозначность в предлагаемом тобой подходе в том, что вот такой вот код:
V>Да, в первом случае будет вызван ReferenceEquals, только я не вижу, чтобы это работало совсем по-разному.
Нет, если в типе MyRefType переопределён оператор == (а разговор-то именно о переопределении операторов), то в первом случае будет вызван он (считаю, что тип myObj так же MyRefType).
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
_FR>Нет, если в типе MyRefType переопределён оператор == (а разговор-то именно о переопределении операторов), то в первом случае будет вызван он (считаю, что тип myObj так же MyRefType).
Никаких "нет", operator== статический, т.е. тебе всё-равно придётся проверять на null первый аргумент (ссылочного типа, напомню). В общем, разница тут будет только в том случае, если твой operator== содержит баги.
Здравствуйте, vdimas, Вы писали:
V>Никаких "нет", operator== статический, т.е. тебе всё-равно придётся проверять на null первый аргумент (ссылочного типа, напомню). В общем, разница тут будет только в том случае, если твой operator== содержит баги.
Разница в том, что при одних аргументах (переменные) будет выполняться один код, а при других (null) — другой.
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, anton_t, Вы писали:
_>>Вызывай _>>
!object.ReferenceEquals(myObj, null)
_>>А то ты хочешь странного: я переопределил оператор, но не хочу что бы он переопределялся.
V>Что-то я не понял рассуждения, ты хочешь сказать, что может быть еще какая-то семантика проверки ссылочного типа на null?
А почему нет? Зачем создавать искусственные нагромождения правил: если тут null, то будет так-то, а если не null то будет по другому, а по средам ещё как-нибудь.
V>P.S. в вызове ReferenceEquals специфицировать object не обязательно.
Можно, но я предпочитаю писать с object
using System;
namespace ConsoleApplication8
{
class Program
{
public static bool ReferenceEquals(Program p1, Program p2)
{
return true;
}
static void Main(string[] args)
{
Console.WriteLine(ReferenceEquals(new Program(), new Program()));
Console.WriteLine(object.ReferenceEquals(new Program(), new Program()));
Console.ReadLine();
}
}
}
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, anton_t, Вы писали:
V>>>P.S. в вызове ReferenceEquals специфицировать object не обязательно. _>>Можно, но я предпочитаю писать с object
_FR>Хоть раз в жизни пригодилось? Чем занимался собственный ReferenceEquals?
Что пригодилось? ReferenceEquals ни разу не переопределял и вам не советую.
Здравствуйте, anton_t, Вы писали:
V>>>>P.S. в вызове ReferenceEquals специфицировать object не обязательно. _>>>Можно, но я предпочитаю писать с object
_FR>>Хоть раз в жизни пригодилось? Чем занимался собственный ReferenceEquals?
_>Что пригодилось? ReferenceEquals ни разу не переопределял и вам не советую.
"писать с object"? Ты сам заявил, почему предпочитаешь "писать с object". Так вот хоть раз в жизни пригодился тот случай, что ты сам в примере привёл?
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, anton_t, Вы писали:
V>>>>>P.S. в вызове ReferenceEquals специфицировать object не обязательно. _>>>>Можно, но я предпочитаю писать с object
_FR>>>Хоть раз в жизни пригодилось? Чем занимался собственный ReferenceEquals?
_>>Что пригодилось? ReferenceEquals ни разу не переопределял и вам не советую.
_FR>"писать с object"? Ты сам заявил, почему предпочитаешь "писать с object". Так вот хоть раз в жизни пригодился тот случай, что ты сам в примере привёл?
Я вообще статические методы стараюсь писать со спецификацией типа, во избежании недоразумений. Если можно легко избежать лишнего бага, зачем его не избегать?
Здравствуйте, _FRED_, Вы писали:
V>>Никаких "нет", operator== статический, т.е. тебе всё-равно придётся проверять на null первый аргумент (ссылочного типа, напомню). В общем, разница тут будет только в том случае, если твой operator== содержит баги.
_FR>Разница в том, что при одних аргументах (переменные) будет выполняться один код, а при других (null) — другой.