Предположу, что вызовется Equals(object)
Поскольку компилятор не знает (нет ограничения where) что тип может быть значимым. Поэтому всё компилирует как для object-ов. Ну и соответственно 10 == null что есть false.
Re[2]: Минутка WTF-20: Меньше кода - меньше ошибок
Здравствуйте, Jack128, Вы писали:
J>Отвечать без компиляции ?? J><Спойлер>
Угу. Студия, впрочем, настаивает на обратном. Невезучая диагностика какая-то.
Здравствуйте, Sharov, Вы писали:
S>Здравствуйте, Sinix, Вы писали:
S>>Вопрос стандартный: что не так-то?
S>Ответ стандартный: внезапный boxing.
Нет, не боксинг. То как компилируются шаблонные типа/методы.
Если нет ограничения (where), то компилируется всё, как для object типа. Поскольку компилятор не может делать предположений о том, какие типы будут передаваться в runtime
Если в ограничении указан where T: SomeClass то будут компилироваться методы для SomeClass (например можно встрять если иметь иерархию классов у которых переопределены операторы equals, но не заворачивать эти реализации через virtual Equals). Тут уже компилятор знает, что как минимум SomeClass будет, а не object общий, потому так.
Re[2]: Минутка WTF-20: Меньше кода - меньше ошибок
V>Предположу, что вызовется Equals(object) V>Поскольку компилятор не знает (нет ограничения where) что тип может быть значимым. Поэтому всё компилирует как для object-ов. Ну и соответственно 10 == null что есть false.
Здравствуйте, yenik, Вы писали:
V>>Предположу, что вызовется Equals(object) V>>Поскольку компилятор не знает (нет ограничения where) что тип может быть значимым. Поэтому всё компилирует как для object-ов. Ну и соответственно 10 == null что есть false.
Y>А почему так работает правильно?
Y>
V>>>Предположу, что вызовется Equals(object) V>>>Поскольку компилятор не знает (нет ограничения where) что тип может быть значимым. Поэтому всё компилирует как для object-ов. Ну и соответственно 10 == null что есть false.
Y>>А почему так работает правильно?
Y>>
Здравствуйте, yenik, Вы писали:
V>>Предположу, что вызовется Equals(object) V>>Поскольку компилятор не знает (нет ограничения where) что тип может быть значимым. Поэтому всё компилирует как для object-ов. Ну и соответственно 10 == null что есть false.
Y>А почему так работает правильно?
Y>
Equals(value, default) — означает вызывать метод Equals c первым параметром value и вторым "по умолчанию" для типа второго аргумента. Т.е Equals(object, object) будет вызван как Equals(value, default(object))
Во втором случае вы явно указываете какого типа значение по умолчанию нужно брать.
Здравствуйте, vasmann, Вы писали:
V>Нет, не боксинг. То как компилируются шаблонные типа/методы. V>Если нет ограничения (where), то компилируется всё, как для object типа. Поскольку компилятор не может делать предположений о том, какие типы будут передаваться в runtime
where тут не причем. Для T без проблем можно правильно сформировать дефолтное значение. Тут проблема в Equals. Она не обобщенная, а принимает два object. Соответственно компилятор не может вывести тип для default и подставляет null (для object). Ну, а Equals считает 0 и null разными значениями (не С++ все же).
Если задать тип явно default(T) или использовать дженерик-метод:
Здравствуйте, Kolesiki, Вы писали:
K>Если код выглядит правильно, а работает — неправильно, ткнуть в него носом всех этих Липпертов и как в школе: "Переписывай заново, двоечник!".
Тут не переписывать надо, а ворнинг в компилятор добавить. default не имеет особого смысла для object-а, так как default без параметров — это указание компилятору вывести тип из использования. А вывод object бесполезен.
Ну, и с наследством этим кривым — Equals-ом на object-ах надо давно покончить было. Еще в 2.0 нужно было ввести кроме него еще и обобщенную реализацию вызывающую EqualityComparer<T>.Default.Equals(T, T). Тогда бы она предпочитается компилятором, при разрешении перегрузки и тип бы успешно выводился.
Еще имеет смысл запретить оператор == для ссылочных типов в которых он не определен. Для них == вызывает проверку равенства ссылок, что так же может привести к багам. Человек явно должен указывать, что хочет получить ссылочную эквавалентность, а не логическое равенство. Приводи к object или используй object.ReferenceEquals().
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Минутка WTF-20: Меньше кода - меньше ошибок
Здравствуйте, vasmann, Вы писали:
V>Equals(value, default) — означает вызывать метод Equals c первым параметром value и вторым "по умолчанию" для типа второго аргумента. Т.е Equals(object, object) будет вызван как Equals(value, default(object))
В этом "сценарии" нет смысла. И компилятор должен был бы об этом предупредить. Весь смысл данной темы, что подобные ошибки фиг заметишь в коде. Это грабли о которых надо знать. C++ way (tm)
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Минутка WTF-20: Меньше кода - меньше ошибок
Здравствуйте, VladD2, Вы писали:
VD>Еще имеет смысл запретить оператор == для ссылочных типов в которых он не определен. Для них == вызывает проверку равенства ссылок, что так же может привести к багам. Человек явно должен указывать, что хочет получить ссылочную эквавалентность, а не логическое равенство. Приводи к object или используй object.ReferenceEquals().
Да уж точно. Замена 100500 проверок на null в коде на ReferenceEquals — это прекрасная идея. В Nemerle как, запретил уже?
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Да уж точно. Замена 100500 проверок на null в коде на ReferenceEquals — это прекрасная идея. В Nemerle как, запретил уже?
А причем тут проверка на null? С ней, как раз, никаких проблем нет. Ну, кроме того, что в 90% случаев — это бойлерплэйт-код, который приходится писать из-за убогости языков. null — это специальный литерал. Второй операнд у "х != null" можно автоматом к object приводить.
Речь идет о сравнении двух объектов. Если у них еще к тому же переопределены GetHashcode и Equals — это почти наверняка ошибка. Если это делается намеренно, то лучше это явно указать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Речь идет о сравнении двух объектов. Если у них еще к тому же переопределены GetHashcode и Equals — это почти наверняка ошибка. Если это делается намеренно, то лучше это явно указать.
Оффтоп: большинство предложений в рослиновских репо так и выглядят.
Народ вечно забывает про сложные части (ну или просто про них не знает, тоже бывает) и начинает яростно настаивать на простых, очевидных и неправильных решениях
По теме — double. Там по определению (NaN==NaN) != NaN.Equals(NaN).
И для эстетов,
int? a = null;
int? b = 5;
if (a <= b == Comparer<int?>.Default.Compare(a, b) <= 0) // что не так-то?
...
Re[6]: Минутка WTF-20: Меньше кода - меньше ошибок
Здравствуйте, Sinix, Вы писали:
VD>>Речь идет о сравнении двух объектов. Если у них еще к тому же переопределены GetHashcode и Equals — это почти наверняка ошибка. Если это делается намеренно, то лучше это явно указать.
S>Оффтоп: большинство предложений в рослиновских репо так и выглядят. S>Народ вечно забывает про сложные части (ну или просто про них не знает, тоже бывает) и начинает яростно настаивать на простых, очевидных и неправильных решениях
С тобой практически невозможно спорить. Ты априори прав. Ведь ты сам определяешь, что предложение неправильное, а такими мелочами, как аргументация себя не утруждаешь.
Я, вот, с тобой и спорить не хочу. Я уже более 10 лет пользуюсь языком где "неправильные" предложения отлично работают на практике и оберегают от ряда ошибок. Вот на фига мне тебе что-то доказывать? Продолжай считать правильным только то, что апрувнуто МС и пиши очередные WHF.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Минутка WTF-20: Меньше кода - меньше ошибок
Здравствуйте, VladD2, Вы писали:
VD>С тобой практически невозможно спорить. Ты априори прав. Ведь ты сам определяешь, что предложение неправильное, а такими мелочами, как аргументация себя не утруждаешь.
Ок, принято
Неправильные — не совсем правильное слово. Могу заменить на "в итоге не будут работать без поломки совместимости с существующим .net-кодом", тогда вроде всё верно.
VD>Я, вот, с тобой и спорить не хочу. Я уже более 10 лет пользуюсь языком где "неправильные" предложения отлично работают на практике и оберегают от ряда ошибок. Вот на фига мне тебе что-то доказывать? Продолжай считать правильным только то, что апрувнуто МС и пиши очередные WHF.
Ну так у тебя и нет тяжкого наследия в виде кучи легаси, необходимости дизайна под 95% community и нужды сохранять совместимость с кодом, написанным 17 лет назад, верно?
Народ в .Net Core уже попытался пойти таким путём. Два года это как бы работало, а потом внезапно пришёл фидбэк от крупных клиентов. В итоге ещё два года аврала и у нас снова почти совместимый с .full net FW.
Не в порядке спора, реально интересно: а как ещё в языке одновременно реализовать sql-style операторы для nullables и при этом не поломать словари/sorted set?
Или делаем так, чтобы реализации операторов и стандартных equatable/comparable-интерфейсов не совпадали, или продолжаем наступать на грабли.
Re[5]: Минутка WTF-20: Меньше кода - меньше ошибок
Здравствуйте, VladD2, Вы писали:
AVK>>Да уж точно. Замена 100500 проверок на null в коде на ReferenceEquals — это прекрасная идея. В Nemerle как, запретил уже? VD>А причем тут проверка на null? С ней, как раз, никаких проблем нет. Ну, кроме того, что в 90% случаев — это бойлерплэйт-код, который приходится писать из-за убогости языков. null — это специальный литерал. Второй операнд у "х != null" можно автоматом к object приводить.
Так запретил уже в Немерле или как?
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, VladD2, Вы писали:
VD>>Речь идет о сравнении двух объектов. Если у них еще к тому же переопределены GetHashcode и Equals — это почти наверняка ошибка. Если это делается намеренно, то лучше это явно указать.
S>Оффтоп: большинство предложений в рослиновских репо так и выглядят. S>Народ вечно забывает про сложные части (ну или просто про них не знает, тоже бывает) и начинает яростно настаивать на простых, очевидных и неправильных решениях
Насколько я понимаю, Влад предлагает запрет только для ссылочных типов.
Тогда однозначно a == b будет вызывать operator==, или не будет компилироваться если его нет.
А если нужно ссылочное сравнение, то явно object.ReferenceEquals(a, b) или явное приведение к object: (object)a == b
_NN>Насколько я понимаю, Влад предлагает запрет только для ссылочных типов. _NN>Тогда однозначно a == b будет вызывать operator==, или не будет компилироваться если его нет.
Неа, всё та же ловушка Вроде всё просто и очевидно, на деле нельзя будет сравнивать с null + будет очень неочевидное поведение для dynamic.