C# для профессионалов.Тонкости программирования, 3-е издание

C# для профессионалов.Тонкости программирования, 3-е издание
Автор: Джон Скит
Год: 2014
ISBN: 978-5-8459-1909-0
Страниц: 608
Язык: Русский
Формат: PDF
Размер: 37 Мб

Download

Книга C# ДЛЯ ПРОФЕССИОНАЛОВ. ТОНКОСТИ ПРОГРАММИРОВАНИЯ (C# in Depth) является обновлением предыдущего издания, ставшего бестселлером, с целью раскрытия новых средств языка C# 5, включая решение проблем, которые связаны с написанием сопровождаемого асинхронного кода. Она предлагает уникальные сведения о сложных областях и темных закоулках языка, которые может предоставить только эксперт Джон Скит.
Если вы занимаетесь разработкой приложений .NET, то будете использовать C# как при построении сложного приложения уровня предприятия, так и при ускоренном написании какого-нибудь чернового приложения. В C# 5 можно делать удивительные вещи с помощью обобщений, лямбда-выражений, динамической типизации, LINQ, итераторных блоков и других средств. Однако прежде их необходимо должным образом изучить.
Третье издание книги было полностью пересмотрено с целью раскрытия новых средств версии C# 5, включая тонкости написания сопровождаемого асинхронного кода. Вы увидите всю мощь языка C# в действии и научитесь работать с ценнейшими средствами, которые эффективно впишутся в применяемый набор инструментов. Кроме того, вы узнаете, как избегать скрытых ловушек при программировании на C# с помощью кристально чистых объяснений вопросов, касающихся внутреннего устройства языка.

+

Структура книги проста. Есть пять частей и три приложения. Первая часть служит введением, включая повторение тем, связанных с C# 1, которые важны для понимания более поздних версий языка и часто вызывают путаницу. Во второй части раскрываются новые средства версии С# 2, в третьей рассматривается версия C# 3 и т.д.

Бывают случаи, когда организация материала подобным образом означает, что мы будем возвращаться к какой-то теме пару раз — в частности, делегаты были усовершенствованы в C# 2 и затем еще раз в C# 3, — но в моем безрассудстве смысл все же присутствует. Я предвижу, что некоторые читатели будут применять в разных проектах разные версии языка; например, на работе вы можете использовать C# 4, а дома экспериментировать с C# 5. Это значит, что удобно пояснять, что к какой версии относится. Кроме того, такая организация способствует ощущению контекста и эволюции — она отражает то, каким образом язык развивался с течением времени.

В главе 1 устанавливается сцена, для чего берется простой фрагмент кода C# 1 и затем развивается, чтобы продемонстрировать, каким образом последующие версии позволяют исходному коду становиться более читабельным и мощным. Мы взглянем на исторический контекст, в котором расширялся язык С#, и технический контекст, в котором он действует в качестве завершенной платформы; C# как язык построен на библиотеках платформы и мощной исполняющей среде для превращения абстракции в реальность.

В главе 2 мы снова будем иметь дело с C# 1, рассматривая три специфичных аспекта; делегаты, характеристики системы типов и разницу между типами значений и ссылочными типами. Эти темы часто понимаются разработчиками на C# 1 в стиле “лишь относительно хорошо”, но поскольку язык C# развивался и значительно усовершенствовал их, для освоения большинства новых средств требуется глубокое понимание основ.

В главе 3 обсуждается крупнейшее средство C# 2, потенциально самое трудное для освоения: обобщения. Методы и типы могут быть написаны обобщенным образом, с параметрами типов, указанными вместо реальных типов, которые задаются в вызывающем коде. Поначалу обобщения будут казаться не менее запутанными, чем это описание, но после того, как вы их поймете, вы непременно удивитесь, как в принципе могли обходиться без них ранее. Если вам когда-либо хотелось представлять целочисленное значение, равное null, то глава 4 как раз для вас. В ней рассматриваются типы, допускающие null: средство, построенное на основе обобщений, которое использует в своих интересах поддержку со стороны языка, исполняющей среды и инфраструктуры.

В главе 5 описаны усовершенствования делегатов в C# 2. До сих пор делегаты можно было применять только для обработки событий, таких как щелчки на кнопках. В C# 2 упростилось создание делегатов, а библиотечная поддержка сделала их более удобными в ситуациях, отличных от обработки событий.

В главе 6 будут исследоваться итераторы и легкий способ их реализации в C# 2. Итераторные блоки используют лишь немногие разработчики, но поскольку технология LINQ to Objects построена на основе итераторов, они будут становиться все более и более важными. Ленивая природа их выполнения также является ключевой частью LINQ.

В главе 7 представлено несколько мелких средств, введенных в C# 2, каждое из которых делает жизнь чуть более приятной. Проектировщики языка сгладили несколько шероховатостей в C# 1, сделав возможным более гибкое взаимодействие с генераторами кода, улучшив поддержку вспомогательных классов, обеспечив более гибкий доступ к свойствам и т.д.

В главе 8 снова раскрывается несколько относительно простых средств, но на этот раз из версии C# 3. Почти весь новый синтаксис приспособлен к общей цели технологии LINQ но строительные блоки также полезны и сами по себе. Благодаря анонимным типам, автоматически реализуемым свойствам, неявно типизированным локальным переменным и существенно улучшенной поддержке инициализации, C# 3 становится намного более мощным языком для выражения необходимого поведения.

В главе 9 рассматривается первая крупная тема, связанная с C# 3 — лямбда-выражения. Не довольствуясь и без того достаточно лаконичным синтаксисом, который обсуждался в главе 5, проектировщики языка еще больше упростили создание делегатов по сравнению с C# 2. Лямбда-выражения способны на большее — они могут быть преобразованы в деревья выражений, которые являются мощным способом представления кода в виде данных.

В главе 10 будут исследоваться расширяющие методы, которые позволяют заставить компилятор считать, что методы, объявленные в одном типе, на самом деле принадлежат другому типу. На первый взгляд они выглядят кошмаром в плане читабельности, но если хорошо подумать, то это исключительно мощное средство, к тому же являющееся жизненно важным для LINQ.

Глава 11 объединяет три предыдущих главы в форме выражений запросов – лаконичным, но мощным способом запрашивания данных. Первоначально мы сосредоточим внимание на LINQ to Objects, но вы увидите, что шаблон выражений запросов применяется так, что позволяет легко подключать других поставщиков данных.

В главе 12 предлагается краткий обзор разнообразных сценариев использования LINQ. Сначала мы взглянем на преимущества выражений запросов, скомбинированных с деревьями выражений, демонстрируя способность LINQ to SQL преобразовывать то, что выглядит как нормальный код С#, в операторы SQL. Затем мы перейдем к рассмотрению способов проектирования библиотек для хорошего сочетания с LINQ взяв в качестве примера LINQ to XML. Двумя альтернативными подходами к внутрипроцессиым запросам являются Parallel LINQ и Reactive Extensions, а в завершение главы приводятся рассуждения о том, как можно расширить LINQ to Objects собственными операциями LINQ.

Рассмотрение версии C# 4 начинается в главе 13, в которой раскрываются именованные аргументы и необязательные параметры, улучшения во взаимодействии с СОМ и обобщенная вариантность. В некотором смысле все они являются совершенно разными средствами, но именованные аргументы и необязательные параметры способствуют взаимодействию с СОМ. а также более специфичным возможностям, которые доступны только при работе с объектами СОМ.

В главе 14 описана единственное крупное средство С# 4: динамическая типизация. Возможность динамической привязки членов во время выполнения вместо статической на этапе компиляции является серьезным концептуальным отклонением для языка С#, но она применяется выборочно — выполняться динамически будет только код, в котором задействовано динамическое значение.

Глава 15 посвящена асинхронности. В C# 5 содержится только одно главное средство — возможность написания асинхронных функций. Это единственное средство одновременно сложно в понимании и элегантно в использовании. Наконец-то стало возможным написание кода, который не выглядит подобно спагетти.

В главе 16 рассматриваются оставшиеся средства C# 5 (оба они крошечные) и приводятся некоторые мысли о будущем.

Приложения содержат справочный материал. В приложении А описаны стандартные операции запросов LINQ с несколькими примерами. В приложении Б рассматриваются основные обобщенные классы и интерфейсы коллекций. В приложении В предоставляется краткое описание разных версий .NET, включая разновидности наподобие Compact Framework и Silverlight.

Изменение стиля разработки в C#

Знаете, что мне по-настоящему нравится в динамических языках, таких как Python, Ruby и Groovy? Они отбрасывают из кода все незначительное, оставляя только его сущность — части, которые действительно что-то делают. Скучная формальность уступает дорогу средствам наподобие генераторов, лямбда-выражений и списковых включений.

Интересно отметить, что некоторые средства, стремящиеся придать динамическим языкам легковесный характер, ничего не делают для обеспечения своей динамичности. Разумеется, определенные средства это делают — например, утиная (неявная) типизация и “магия”, используемая в Active Record — но статически типизированные языки не обязательно должны быть неуклюжими и тяжеловесными.

Давайте обратимся к С#. В некотором смысле язык C# 1 можно рассматривать как улучшенную версию языка Java образца примерно 2001 года. Все сходства были слишком очевидными, но в C# имелось несколько дополнений: свойства как основополагающая характеристика языка, делегаты и события, циклы foreach, операторы using, явное переопределение методов, перегрузка операций и специальные тины значений — и это далеко не полный перечень. Понятно, что предпочтения относительно языка — личное дело каждого, однако я воспринимал C# 1 как шаг вперед от Java, когда только начал пользоваться им.

В тех пор все становилось только лучше. В каждую новую версию добавлялись важные средства, снижающие инстинктивный страх разработчиков, причем всегда в тщательно продуманной манере и с минимальной обратной несовместимостью. Даже до появления в C# 4 возможности применения динамической типизации там. где она действительно удобна, многие средства, традиционно связываемые с динамическими и функциональными языками, нашли свое отражение в С#, позволяя получать код, который проще в написании и сопровождении. Аналогично, хотя средства, касающиеся асинхронной обработки, в C# 5 не точно совпадают с такими средствами в F#, мне кажется, что последние оказали определенное влияние.

В настоящей книге я последовательно проведу вас по всем изменениям, предоставляя достаточно деталей, чтобы вы спокойно воспринимали те удивительные вещи, которые компилятор C# теперь готов предложить. Тем не менее, обо всех них пойдет речь позже — в этой главе я в бешеном темпе постараюсь осветить столько, сколько смогу, едва переводя дыхание. Я объясню, что имеется в виду при сопоставлении C# как языка и .NET как платформы, и предоставлю несколько важных замечаний относительно кода примеров для остальных частей книги. После этого можно углубляться в детали.

В этой одной главе мы не собираемся охватить абсолютно все изменения, внесенные в язык С#. Тем не менее, мы рассмотрим обобщения, свойства с различными модификаторами доступа, типы, допускающие значения null, анонимные методы, автоматически реализуемые свойства, усовершенствованные инициализаторы коллекций и объектов, лямбда-выражения, расширяющие методы (часто называемые также методами расширения), неявную типизацию, выражения запросов LINQ, именованные аргументы, необязательные параметры, упрощенное взаимодействие с СОМ, динамическую типизацию и асинхронные функции. Это проведет нас по всему пути от C# 1 до последней версии. C# 5. Итак, приступим.