Здравствуйте, уважаемые
читатели. В этой статье представлю краткий обзор книги Билла Вагнера "Effective C#". Один из известных MVP в Украине – Сергей Тепляков – уже давал краткий обзор неточностей этой книги в
своей статье "О книге Билла Вагнера "EffectiveC#", я лишь немного их дополню своими наблюденями.
Книги из серии Effective начал
Скотт Мейерс в 1997 году свой книгой "Effective C++". Сейчас доступно третье издание этой книги "Effective C++: 55 Specific Ways to Improve Your Programs and Designs". Так вот: независимо от того, что
книга Билла Вагнера из этой серии, по содержимому она не дотягивает
до книги Мейерса. Не могу сказать о том, что книга не
стоит прочтения. Тут проблема в другом: если Вы далеко не начинающий разработчик и
прочитали как минимум с пониманием Рихтера и, например, книгу Джона Скита "C# in Depth, 3rd Edition", то пользы от этой книги будет мало.
Приведу краткий перечень неточностей, замеченных Сергеем Тепляковым, так как они отличаются от тех, которые нашел я.
Приведу краткий перечень неточностей, замеченных Сергеем Тепляковым, так как они отличаются от тех, которые нашел я.
Неточность #1.Переопределение статических методов
«You never override the
static Object.Reference and static Object.Equals() because they provide the
correct tests, regardless of the runtime type.»
Неточность #2. Время жизни локальных переменных
All reference types, even
local variables, are allocated on the heap. Every local variable of a reference
type becomes garbage as soon as the function exits.
Неточность #3. Об операторе ==
«No matter what type is
involved, a == a is always true.»
Неточность #4. Виртуальность интерфейсов
«Members declared in interfaces are not virtual – at least, not by
default. Interface methods are not virtual. When you implement
an interface, you are declaring a concrete implementation of a particular
contract in that type».
Неточность
#5. Порядок создания объектов
«Here
is the order of operations for constructing the first instance of a type:
1.
Static variable storage is set to 0.
2. Static variable initializers execute.
3.
Static constructors for the base class execute.
4. The static constructor executes.
5. …»
Неточность #6.
Об итераторах коллекций
«The .NET Framework
designers followed the same pattern with the other collection classes:
Dictionary<T> contains a private DictionaryEnumerator<T>,
Queue<T> contains a QueueEnumerator<T>, and so on. The enumerator
class being private gives many advantages…»
Приведу неточности, которые заметил я. Первая проблема – в первом же совете, в котором автор рекомендует использовать проперти, вместо доступных открытых данных. Вроде и все расписано, и рассказано о валидации, и о прочих прелестях проперти. Но если копнуть глубже, то лучше в этом плане дает совет Рихтер по поводу использования properties вместо открытых данных в своей книге "CLR via C#". Тот же Рихтер говорит о том, что не нужно злоупотреблять автопроперти. Вагнер об этом не пишет ни слова. Этот совет вряд ли вам расскажет о чем-то новом. Я не считаю данный совет неточным, я его просто считаю неполным, поскольку привел источник, в котором такой же совет занимает меньше в описании и доносит до читателей больше, чем это делает Вагнер.
Третий совет из этой серии о предпочтении использования is/as оператора, по сравнению с Cast, – неполный. О преобразовании к value type упоминается
только вскользь. Возможно, это не является глобальной проблемой, но если вы посмотрите
об этот пост Эрика Липперта, то заметите очень большую разницу (What's the difference between "as" and "cast" operators?). В
итоге мы можем ознакомиться с интересующей нас темой либо у Липперта в нескольких абзацах, или читать совет, часть из которого, к сожалению, – просто
вода.
Небольшой отход от неточностей и критики некоторых советов: хотелось бы
упомянуть об еще одной детали, которая наблюдается у Вагнера по всей книге. Если для написания какой-то заметки нужны примеры, то сначала
идут некорректные примеры или примеры, которые нежелательно использовать на
практике, и в конце совета – нормальный пример. В итоге имеем кучу информации,
полезной из которой − около 20%. Возможно, некоторым разработчикам нравится
такой подход. Меня же такое описание немного нервировало.
Также спорный совет по поводу переопределения для классов метода ToString(). К сожалению,
совет имеет мало общего с практическим применением. Как часто для своих классов вам приходится
вызывать метод ToString()? А переопределять для каждого класса данный
метод, который с вероятностью 80% никогда не будет использован, – нецелесобразный.
Анализ этого совета я сделал, проанализировав несколько коммерческих и open sources проектов.
Очень не понравился совет по инициализации членов статических классов: "Use Proper Initialization
for Static Class Members". В совете
не рассказано о проблеме, которая называется double check locking in singleton pattern. Более детально об синглтоне можно посмотреть в примере "Implementing Singleton in C#" на MSDN, а лучше посмотреть статью Скита "Implementing the Singleton Pattern in C#". Из этих статей можно почерпнуть больше, чем с
совета Вагнера. Признаюсь честно: если бы я не знал, как это работает и что
упустил Вагнер, я бы, наверное, не понял, что автор хотел донести этим советом.
Один из советов, который действительно понравился, – это "Ensure That 0 Is a Valid State for Value
Types". В нем рассказывается, что 0 – не всегда актуальное значение для value type, и приводится пример с enum.
Также в примере автора к рекомендации "Implement the Event Pattern for Notifications" пример,
который приведен для данного совета, некорректен. Во-первых, пример
с логгером, у которого нужно добавить нотификацию, мягко говоря, странный. У него
есть огромная проблема: достаточно хоть одному из подписанных событий пробросить ошибку – и прервётся вся цепочка уведомлений. Более детально, как такое побороть,
можно посмотреть в статье "Обработка ошибок в C#".
Слишком сложный пример для того, чтобы донести свою мысль до
читателей.
Одним из неуместных примеров также оказался совет 30 "Prefer Overrides to Event
Handlers". Возможно, для разработчиков,
которые работают не с WPF, этот пример может показаться таким, который имеет право на существование, но в реальных примерах принято использовать
паттерн MVVM и вместо событий использовать паттерн Command.
Немного сожалею
о том, что не было возможности цитировать неточности данной книги в ридере.
Из-за этого часть из них просто не смог вспомнить. В целом книга неплохая. Она
уникальная в своем роде. Если подытожить, то по пятибалльной шкале книга
заслуживает оценку 3. Думаю, что опытные разработчики смогут подчеркнуть некоторые
ценные моменты из данной книги. Книга для тех, кто любит постоянно черпать
новые знания. Суммарная оценка – "удовлетворительно".
No comments:
Post a Comment