Предположу, что вызовется 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 — это почти наверняка ошибка. Если это делается намеренно, то лучше это явно указать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.