Visual Studio 2010 и новые возможности C# 4.0
5 октября 2010
Рубрика: Обзоры и мнения.
Автор: Андрей Скляревский.

visual_5_10_2010

В апреле 2010 года был выпущен новый набор инструментов для разработчиков от Microsoft — Visual Studio 2010. Несмотря на то, что на первый взгляд новая среда разработки является эволюционным этапом развития предыдущей версии, на деле множество ее частей были переписаны с нуля: например, основой для интерфейса теперь является Windows Presentation Foundation, что позволяет использовать больше доступных ресурсов компьютера за счет привлечения аппаратного ускорения графики, улучшает возможности по расширению Visual Studio и предоставляет разработчикам большую гибкость настройки внешнего вида среды согласно своим предпочтениям.

Однако, данное новшество можно рассматривать скорее как приятное улучшение, нежели чем фундаментальное продвижение вперед. Среди более серьезных нововведений следует отметить:
• новую библиотеку классов и среду исполнения .NET 4.0 Series;
• возможность нацеливания проектов на любую версию .NET, начиная с .NET 2.0, включая облегченные Client Profile версии;
• поддержку нескольких мониторов;
• новые возможности по поиску и навигации внутри кода больших проектов (окно Navigate To (рис.1) можно вызвать одновременным нажатием на Control и запятую в английской раскладке клавиатуры);
• усовершенствования в JavaScript IntelliSense;
• URL Routing, позволяющий удобно перенаправлять запросы как для ASP.NET MVC, так и для Web Forms проектов;
• упрощение Web.config файлов в ASP.NET проектах;
• новый синтаксис <%: %> в ASP.NET, который отличается от обычного <%=%> тем, что кодирует специальные символы, использующиеся в HTML для обозначения разметки, такие как <, >, и &, что позволяет избавиться от вызовов HttpUtility.HtmlEncode, использовавшихся для этих целей ранее;
• шаблоны проектов на основе ASP.NET MVC Framework 2, при этом Microsoft заявляет, что обе методологии разработки веб-приложений — веб-формы и MVC будут поддерживаться на равноправной основе и далее;
• шаблоны проектов для Silverlight 3;
• новые элементы управления DataGrid, DatePicker, Calendar, поддержка Pixel Shader 3, а также эффекты сглаживания анимаций и достаточно много других новшеств в Windows Presentation Foundation.

visual_5_10_2010_1

В области непосредственного программирования Visual Studio 2010 имеет существенное отличие от своих предшественниц в виде интеграции языка Visual F# в основной набор языков, доступных для использования при стандартной установке (рис. 2).

visual_5_10_2010_2

Несмотря на то, что для F# по-прежнему отсутствуют стандартные шаблоны для WPF и ASP.NET проектов, он доступен для использования наряду с C++, C++/CLI, C# и Visual Basic.NET без необходимости в установке дополнительных расширений, как это было ранее. С точки зрения популяризации функционального программирования, это нововведение можно считать серьезным шагом вперед, т.к. есть все основания полагать, что именно оно станет локомотивом программирования в будущем. Вычисление и вывод числа Фибоначчи номер 7 на F# выглядит следующим образом:

let rec fibonacci x =
match x with
0 -> 1
| 1 -> 1
| n -> fibonacci(x — 1) + fibonacci(x — 2)

printfn «%d» (fibonacci 7)

Флагманский .NET язык C# обновился до версии 4.0. Если C# 3.0 можно считать во многом революционным, т.к. его новые декларативные конструкции позволили разработчикам писать существенно меньше кода, то новшества C# 4.0 больше относятся к разряду эволюционных и необходимых для упрощения решения конкретного ряда задач. Тем не менее, автор данной статьи полагает, что новшества, внесенные в C# 4.0, могут быть переоценены позже, т.к. имеют серьезный потенциал стать основой для концептуально новых подходов в разработке.

Создатели C# 4.0 определили в качестве основного фокуса для нового языка и .NET 4 совместимость и взаимодействие с другими средами, в частности с COM, включая компоненты Microsoft Office, и динамическими средами, исполняющими программы на таких языках, как Python и Ruby. В то же время C# 4.0 сохранил за собой статус языка со статической типизацией, полностью поддерживает код, написанный на предыдущих версиях языка, а также устранил некоторые ранее имевшиеся затруднения по преобразованию generic-типов.

Основным новшеством является ключевое слово dynamic. Тип dynamic позволяет осуществлять операции над своими экземплярами на этапе исполнения приложения, игнорируя стандартные проверки на этапе компиляции. Разработчикам, знакомым с языками с динамической типизацией, такими как PHP, JavaScript и другими, скорее всего, будет легко разобраться с новым ключевым словом в C#. Тип dynamic на уровне .NET реализован через среду исполнения Dynamic Language Runtime, включенную в .NET 4.0. Он не является привязанным к конкретному .NET типу, и, следовательно, может быть использован во множестве сценариев. Разработчик также может написать и свой тип, реализующий динамическую привязку к операциям через реализацию интерфейса IDynamicMetaObjectProvider, или наследование от класса DynamicObject. Интересным фактом является то, что подобная реализация позволяет осуществлять вызов методов и свойств, которых на самом деле нет, обрабатывая их названия надлежащим образом. Например, вполне возможно реализовать динамический объект планировщик, который при обращении следующего вида:

scheduler.On12July10pm(() => Console.WriteLine(«10 July, 10:00pm.»)),

записывал бы в свою таблицу необходимость вывести на консоль нужное сообщение в 10 вечера 12 июля. Таким образом, тип dynamic открывает перспективы для реализации т.н. «domain-specific languages» (DSL) — специфических конструкций внутри обычных языков, упрощающих работу с конкретным набором объектов. Например, в Интернете уже появились (http://www.justnbusiness.com/post/2009/07/08/The-Illusion-of-Strongly-Typed-XML-with-C.aspx) реализации DSL для XML на основе наследования от DynamicObject.
На практике тип dynamic позволяет сильно облегчить взаимодействие с COM, в частности, в случае использования объектов Microsoft Office. Кроме этого, он, естественно, превосходно подходит для случая взаимодействия с динамическими языками и библиотеками, написанными на них. Однако, он никак не влияет на концепцию C# как языка со статической типизацией, лишь внося определенное упрощение с целью усовершенствования механизмов взаимодействия с другими средами исполнения. Так, если при взаимодействии с Excel в C# 3.0 код мог выглядеть примерно следующим образом:

((Excel.Range)excelApp.Cells[1, 1]).Value2 = «Name»;
Excel.Range range2008 = (Excel.Range)excelApp.Cells[1, 1],

то в C# 4.0 подобная задача будет решаться куда более простой и понятной записью:

excelApp.Cells[1, 1].Value = «Name»;
Excel.Range range2010 = excelApp.Cells[1, 1].

Другим новшеством C# 4.0 являются опциональные и именованные параметры, которые были реализованы в целях улучшения механизмов взаимодействия с COM, а также для упрощения кода вызова методов с большим количеством параметров. Теперь при вызове некоторых методов COM объектов Microsoft Office, принимающих порядка 30 параметров, можно будет указать значения только нужным. Представим следующий гипотетический код в C# 3.0:

static int CalculateAmount(int quantity, int price, bool addProfit) {
return quantity * price + (addProfit ? 10 : 0);
}
Console.WriteLine(CalculateAmount(0, 0, true)); // 10
Console.WriteLine(CalculateAmount(7, 10, false)); // 70
Console.WriteLine(CalculateAmount(0, 0, false)); // 0

При использовании компилятора C# 4.0 можно провести небольшие изменения, сделав все параметры метода CalculateAmount опциональными:

static int CalculateAmount(int quantity = 0, int price = 0, bool addProfit = false) {
return quantity * price + (addProfit ? 10 : 0);
}
Console.WriteLine(CalculateAmount(addProfit: true)); // 10
Console.WriteLine(CalculateAmount(quantity: 7, price: 10)); // 70
Console.WriteLine(CalculateAmount(7, 10)); // 70
Console.WriteLine(CalculateAmount()); // 0

Последним ключевым улучшением в C# 4.0 является ковариантность и контравариантность. Если ранее было невозможно преобразовать IEnumerable<string> к IEnumerable <object>, то теперь это возможно, т.к. тип string наследуется от object. Однако, преобразование List<string> к List<object> выдаст ошибку компилятора, т.к. в этом случае после преобразования в список можно было бы добавлять объекты, которые он не поддерживает.

Ковариантность означает, что параметр, тип которого объявляется как generic, всегда является возвращаемым. Например, можно безопасно преобразовать Func<string> к Func<object>, т.к. string наследуется от object и работоспособность самого делегата не зависит от того, как будет использоваться возвращаемое значение. С другой стороны, Func<object> привести к Func<string> не всегда представляется возможным, т.к. не каждый объект, который возвратит оригинальный делегат, может быть приведен к типу string. Подобным образом в C# 4.0 существует прямое преобразование IEnumerable<string> к IEnumerable<object> и IQueryable<string> к IQueryable<object>.

public interface IEnumerable<out T> : IEnumerable {…} //
параметр T ковариантен

В отличие от ковариантности, контравариантность объявляет, что параметр всегда является принимаемым. В частности, логичным является преобразование Action<object> к Action<string>, т.к. объект типа string всегда можно передать в делегат в качестве аргумента типа object. Но при этом делегат типа Action<string> невозможно преобразовать к Action<object>, т.к. делегат рассчитывает, что ему будет передан аргумент типа string, и предположительно осуществляет операции над строкой. Подобным образом объект, тип которого реализует интерфейс IComparer<object>, может быть приведен к типу IComparer<string>, т.к. ему достаточно для сравнения тех методов и свойств, которые есть в типе object, точно присутствующие и в типе string.

public delegate void Action<in T>(T obj); //
параметр T контравариантен

Появилось также и понятие инвариантности, когда параметр может быть как принимаемым, так и возвращаемым. Примером является параметр класса List<T>. Если класс A является базовым для класса B, являющегося базовым для класса C, то List<C> не может быть преобразован к типу List<B>, т.к. в таком случае в него можно было бы добавлять объекты типа B, на которые он не рассчитывает. С другой стороны, List<B> нельзя преобразовать к List<C>, т.к. это наложило бы более узкое ограничение на добавляемые объекты и привело бы к проблеме с объектами типа B, уже находившимися в списке на момент преобразования. По этой же причине List<A> нельзя преобразовать ни к типу List<B>, ни к типу List<C>. Тем не менее, List<B> и List<C> могут быть совершенно свободно приведены к типу IEnumerable<A>, т.к. IEnumerable<T> позволяет только перечислять элементы, но не добавлять новые.

В целом, C# 4.0 является существенным шагом к упрощению взаимодействия с другим программным обеспечением, а также к снижению лишнего кода по преобразованию типов. В то же время Navigate To и другие новшества Visual Studio 2010 позволяют разработчикам больше концентрироваться на коде и реальных задачах, затрачивая меньше времени на рутину.

Orphus system
В Telegram
В Одноклассники
ВКонтакте