Comments 21
«No matter what type is involved, a == a is always true.»
На самом деле, для платформы .NET это правило исполняется не всегда. А вы можете привести пример, когда это условие нарушается?
double.NaN == double.NaN
+8
Или когда оператор переопределён и возвращает true/false в зависимости от Random :)
+7
class Program {
static int cntr=0;
static int a { get { return ++cntr; } }
static void Main(string[] args) {
Console.WriteLine("{0}",a==a);
}
}
Напечатала false. Безо всяких переопределений сравнения.
+3
>> Любой программист, пришедший в .NET из С++ ответит положительно (ведь так быстрее!), потом он прочитает о проблемах и его мнение наверняка изменится на противоположное.
Ни один программист пришедший из c++ никогда не изменит свое мнение. В с++ это не считается проблемами, в с++ весь геморой которым борешься пол жизни считается наградой, выслугой лет.
А те кто изменяет свое мнение (например после шарпа), никогда не возвращается назад в с++.
Ни один программист пришедший из c++ никогда не изменит свое мнение. В с++ это не считается проблемами, в с++ весь геморой которым борешься пол жизни считается наградой, выслугой лет.
А те кто изменяет свое мнение (например после шарпа), никогда не возвращается назад в с++.
+8
Неточность #3. Об операторе ==
«No matter what type is involved, a == a is always true.»
Это предложение не является неточностью, оно очень неудачно выдернуто из контекста:
… you need to keep in mind the mathematical properties of equality: Equality is reflexive, symmetric, and transitive. The reflexive property means that any object is equal to itself. No matter what type is involved, a == a is always true.
То есть
a == a is always trueэто всего лишь определение рефлексивности.
Вообще же автор пишет о том, как должен работать оператор сравнения в том случае если программист решит его переопределить, а не о том как он на самом деле работает.
+2
Спасибо за добавление контекста, в этом случае неточность становится более четкой:) Дело в том, что в .NET-е, рефлексивность обязан обеспечивать метод Equals, но ее нет у оператора ==.
Это одна из причин (помимо того, что оператор == не полиморфный), почему для определения эквивалентности объектов в том же Dictionary используется именно Equals, а не оператор ==.
И Double.NaN является известным примером, когда Equals остается рефлексивным, а оператор == — нет.
Это одна из причин (помимо того, что оператор == не полиморфный), почему для определения эквивалентности объектов в том же Dictionary используется именно Equals, а не оператор ==.
И Double.NaN является известным примером, когда Equals остается рефлексивным, а оператор == — нет.
+2
Если я не ошибаюсь, NaN по стандарту себе не равен, и не только для C#, что предполагает, что NaN не принадлежит типу, для которого должна обеспечиваться рефлексивность.
0
double.NaN хитрый зверь:
double.NaN.Equals(double.NaN) — true
double.NaN == double.NaN — false
Просто если бы не работал Equals, то вы бы не смогли из словаря double.NaN достать.
double.NaN.Equals(double.NaN) — true
double.NaN == double.NaN — false
Просто если бы не работал Equals, то вы бы не смогли из словаря double.NaN достать.
0
Equals видимо не подпадает видимо под действие стандарта.
На википедии, кстати, написано, NaN себе не равен по стандарту IEEE 754. И там кстати также написано, почему так. NaN может быть получен от деления на ноль, от извлечения корня из отрицательного числа, и т.п. Записывается результат одинаково, а вот получить равенство результатов вышеперечисленных операций было бы фейлом.
Так что с рефлексивностью у оператора == все в порядке.
На википедии, кстати, написано, NaN себе не равен по стандарту IEEE 754. И там кстати также написано, почему так. NaN может быть получен от деления на ноль, от извлечения корня из отрицательного числа, и т.п. Записывается результат одинаково, а вот получить равенство результатов вышеперечисленных операций было бы фейлом.
Так что с рефлексивностью у оператора == все в порядке.
+1
Неточность #5. Порядок создания объектовВыглядит как вырванное из контекста. Ну т.е. при создании экземпляра операции действительно выполняются в таком порядке. Аналогично:
1. Static variable storage is set to 0.— если статических членов нет, то и устанавливаться в ноль ничего не будет.
0
Речь немного не об этом. Речь о выделенном, что при создании экземпляра вначале вызывается статический конструктор базового класса, а потом статический конструктор наследника. В некоторых случаях (при наличии атрибута beforefieldinit у типа), при создании экземпляра наследника даже вызов статического конструктора наследника не гарантируется (подробности здесь).
Но даже в базовом случае, порядок вызова статических конструкторов противоположен порядку вызова экземплярных конструкторов: экземплярные конструкторы взываются от базового к наследнику, а статические конструкторы — от наследника к базовому.
Вот пруф:
При вызове new Derived() на экране мы получим следующее:
Но даже в базовом случае, порядок вызова статических конструкторов противоположен порядку вызова экземплярных конструкторов: экземплярные конструкторы взываются от базового к наследнику, а статические конструкторы — от наследника к базовому.
Вот пруф:
internal class Base
{
public Base()
{
Console.WriteLine("Base.ctor");
}
static Base()
{
Console.WriteLine("Base.cctor");
}
}
internal class Derived : Base
{
public Derived()
{
Console.WriteLine("Derived.ctor");
}
static Derived()
{
Console.WriteLine("Derived.cctor");
}
}
При вызове new Derived() на экране мы получим следующее:
Derived.cctor
Base.cctor
Base.ctor
Derived.ctor
0
Я в свое время заказал на Амазоне и Скита, и Вагнера в одной посылке. Сначала прочитал Скита и был в диком восторге. А потом прочитал Вагнера и остался разочарован. Мне не понравилась ультимативность стиля изложения как таковая. Некоторые советы показались надуманными. И да, минимум объяснений на контрасте со Скитом смотрелось очень неинтересно. Книга имеет право на жизнь, но почему она стоит столько же, сколько и «C# in Depth», я не понимаю.
0
мой совет: сначала прочитать CLR via C#, а потом уже Effective C#, и при расхождениях верить первой книжке.
0
А что может автор данной статьи рассказать о плюсах данной книги? Указанные недочеты — это не вся книга.
0
Из плюсов: довольно приличное количество мыслей для размышлений, разбитых по разделам. Начинаешь читать главы по Equals/GetHashCode, любые несогласия с автором вынуждают к определенному ресерчу, который позволяет понять, где же на самом деле правда. И таких «вбросов» достаточно много; на часть из них сам автор дает вменяемые ответы, а вот ответы на другие вбросы придется искать в другом месте.
Возможно недостатки подпортили впечатление сильнее, в результате чего положительные моменты не так сильно отпечатались в памяти. Все будет зависеть от того, что вы читали до этого. Если для вас в книге Скита не много нового, то эту книгу нет смысла читать. Если же у вас пара лет опыта работы с платформой .NET и языком C#, то в книге Вагнера будет много полезного.
Возможно недостатки подпортили впечатление сильнее, в результате чего положительные моменты не так сильно отпечатались в памяти. Все будет зависеть от того, что вы читали до этого. Если для вас в книге Скита не много нового, то эту книгу нет смысла читать. Если же у вас пара лет опыта работы с платформой .NET и языком C#, то в книге Вагнера будет много полезного.
0
А русскоязычный вариант есть?
0
Sign up to leave a comment.
О книге Билла Вагнера «Effective C#»