Visual Studio 2008

Краткий обзор ключевых новинок

Алексей Федоров

Варианты поставки Visual Studio 2008

Требования к системе

Новинки в языках программирования

C# 3.0

Автоматическое создание методов для свойств объектов

Инициализация объектов и коллекций

Типизация переменных и массивов

Методы-расширения

Лямбда-выражения

Visual Basic .NET 9.0

Типизация локальных переменных

Инициализация массивов и объектов

«Пустые» типы

Упрощенные делегаты

 

В этом году Visual Studio отмечает свое десятилетие. Планируемая к выпуску версия Microsoft Visual Studio 2008 включает все лучшее, что появилось в продукте за последние десять лет.

Первая версия Visual Studio была выпущена в 1997 году и состояла из отдельных средств разработки на языках Visual C++, Visual Basic и Visual J++, а также включала продукт под названием Visual InterDev, предназначенный для создания web-приложений с применением JavaScript.

Версия Visual Studio 6.0, в которой появился самый популярный до последнего времени язык разработки Visual Basic 6.0, стала платформой, поддерживающей унифицированный набор сервисов для различных языков программирования, и заложила основу новой архитектуры средств разработки компании Microsoft.

С появлением Visual Studio .NET 2002 и Visual Studio .NET 2003 разработчикам стала доступна технология на базе CRL и .NET Framework. Впервые за всю историю существования средств разработки программисты смогли использовать единый набор средств, включающий визуальные средства дизайна, визуальные компоненты с поддержкой drag and drop и технологию IntelliSense. В то же время начали появляться средства, упрощающие коллективную работу над программными проектами.

В Visual Studio 2005 средства, облегчающие коллективную, командную работу в рамках основных проектных ролей (архитектор, разработчик, тестировщик), увидели свет в виде нескольких специальных ролевых изданий, объединенных названием Visual Studio Team System, и компонента, обеспечивающего фундамент для совместной работы — Visual Studio 2005 Team Foundation Server.

Visual Studio 2008 продолжает традиции, заложенные предыдущими версиями продукта, и содержит множество новинок, предназначенных как для упрощения создания приложений для различных платформ отдельными разработчиками, так и для повышения производительности всей проектной команды.

Новинки, появившиеся в Microsoft Visual Studio 2008, можно разделить на три категории: повышение производительности разработчиков, поддержка новейших технологий и управление всем циклом создания приложений (рис. 1).

 

Рис. 1. Группы ключевых новинок в Visual Studio 2008

К новинкам в области повышения производительности разработчиков можно отнести расширения в языках программирования, поддержку написания кода для нескольких версий .NET Framework (multi-targeting), улучшенные средства интеграции между данными и языками программирования в Visual Basic .NET и C# (технология Language Integrated Query, LINQ), а также существенные улучшения в поддержке создания web-приложений, включающие расширения в дизайнере HTML/CSS и поддержку технологии Intellisense для JavaScript и расширенные средства отладки.

В группе поддержки новейших технологий относятся следующие новинки: поддержка создания приложений для Windows Server 2008, Windows Vista (включая Common Dialogs) и Microsoft Office 2007 (включая новую версию Visual Studio Tools for Office и развертывание через ClickOnce), а также средства для работы с SQL Server 2008. В частности, в Visual Studio 2008 полностью поддерживается создание приложений для платформы .NET Framework 3.0 и 3.5, а также обеспечивается интегрированная поддержка таких технологий, как ASP .NET AJAX и Microsoft Silverlight.

Средства управления циклом создания приложений (Visual Studio Team System) обогатились расширенным набором поддерживаемых ролей, включая издание для работы с базами данных — Team Edition for Database Professionals. Помимо этого расширена функциональность модульного тестирования, обеспечена поддержка нагрузочного тестирования для корпоративных сценариев и реализованы новые средства измерения производительности и диагностики.

В большинстве своем (а всего в Visual Studio 2008 можно насчитать более 200 новых и расширенных функций) эти новинки применимы к разработке web- и Windows-приложений, а также к созданию решений на платформе Microsoft Office, хотя не забыты и приложения для мобильных устройств, а также поддержка создания сервисов. Далее мы поговорим об этом более подробно.

Варианты поставки Visual Studio 2008

Варианты поставки Visual Studio 2008 практически не отличаются от вариантов поставки Visual Studio 2005 (за исключением, наверное, издания для работы с базами данных — Team Edition for Database Professionals) и направлены на удовлетворение потребностей всего сообщества разработчиков — от студентов и энтузиастов (издания семейства Express) до профессиональных разработчиков, входящих в состав проектной группы (Visual Studio Team System) — рис. 2. Некоторые расширения, которые мы обсудим в данном обзоре, — поддержка технологии LINQ, расширения в дизайнере HTML/CSS, дизайнер для Windows Presentation Foundation и O-R-дизайнер — доступны в изданиях семейства Express, в то время как другие (в первую очередь Visual Studio Tools for Office) требуют использования Visual Studio Professional Edition.

 

Рис. 2. Издания Visual Studio 2008

По сравнению с Visual Studio 2005 некоторые продукты семейства Visual Studio получили новые названия, которые приводятся в табл. 1.

Таблица 1. Новые названия продуктов
семейства Visual Studio

Название в Visual Studio 2005

Название в Visual Studio 2008

Visual Studio Team System

Visual Studio Team System 2008

Visual Studio 2005 Team Suite

Visual Studio Team System 2008 Team Suite

Visual Studio 2005 Team Edition for Software Architects

Visual Studio Team System 2008 Architecture Edition

Visual Studio 2005 Team Edition for Software Developers

Visual Studio Team System 2008 Development Edition

Visual Studio 2005 Team Edition for Software Testers

Visual Studio Team System 2008 Test Edition

Visual Studio 2005 Team Edition for Database Professionals

Visual Studio Team System 2008 Database Edition

Visual Studio 2005 Team Foundation Server

Visual Studio Team System 2008 Team Foundation Server

Visual Studio 2005 Team Test Load Agent

Visual Studio Team System 2008 Test Load Agent

Названия остальных изданий продуктов, входящих в семейство Visual Studio, остались прежними — изменилась лишь версия продукта (табл. 2).

Таблица 2. Другие продукты семейства
Visual Studio

Название в Visual Studio 2005

Название в Visual Studio 2008

Visual C# 2005 Express Edition

Visual C# 2008 Express Edition

Visual C++ 2005 Express Edition

Visual C++ 2008 Express Edition

Visual Basic 2005 Express Edition

Visual Basic 2008 Express Edition

Visual Web Developer 2005 Express Edition

Visual Web Developer 2008 Express Edition

Visual Studio 2005 Standard Edition

Visual Studio 2008 Standard Edition

Visual Studio 2005 Professional Edition

Visual Studio 2008 Professional Edition

С помощью средств, включенных в состав Visual Studio 2008, можно создавать приложения для широкого спектра платформ — от так называемых разумных устройств (smart personal objects) до сотовых телефонов, планшетных компьютеров и настольных компьютеров и серверов (рис. 3).

 

Рис. 3. Платформы, поддерживаемые в Visual Studio 2008

Требования к системе

В данном разделе мы рассмотрим основные требования к системе для Visual Studio 2008 и Visual Studio Team System 2008. Visual Studio 2008 может быть установлена на следующие операционные системы:

  • Windows Vista (x86 и x64) — все издания, за исключением Starter Edition;
  • Windows XP (x86 и x64) с установленным пакетом обновлений Service Pack 2 или более поздней версии — все издания, за исключением Starter Edition;
  • Windows Server 2003 (x86 и x64) с установленным пакетом обновлений Service Pack 1 или более поздней версии;
  • Windows Server 2003 R2 (x86 или x64) или более поздней версии;
  • Windows Server 2008 (x86 и x64).

Для установки Visual Studio 2008 потребуется компьютер со следующими характеристиками:

  • процессор с частотой не ниже 1,6 ГГц;
  • минимум 384 Мбайт оперативной памяти (768 Мбайт или более для работы под Windows Vista);
  • 2,2 Гбайт свободного пространства на жестком диске со скоростью не менее 5400 об./мин;
  • дисплей с разрешением не менее 1024Ѕ768;
  • привод DVD.

Издание Microsoft Visual Studio 2008 Team System Team Foundation Server представляет собой многозвенное приложение, компоненты которого могут быть установлены на различных компьютерах. Для установки Visual Studio Team Foundation Server на одном компьютере вам потребуется машина со следующими характеристиками:

  • процессор с частотой не ниже 2,2 ГГц;
  • минимум 2 Гбайт оперативной памяти;
  • 8 Гбайт свободного пространства на жестком диске со скоростью не менее 5400 об./мин;
  • дисплей с разрешением не менее 1024Ѕ768;
  • привод DVD.

Пакет Visual Studio Team Foundation Server может быть установлен на следующие операционные системы:

  • Windows Vista (x86 и x64) — все издания, за исключением Starter Edition;
  • Windows XP (x86 и x64) с установленным пакетом обновлений Service Pack 2 или более поздней версии — все издания, за исключением Starter Edition;
  • Windows Server 2003 (x86 и x64) с установленным пакетом обновлений Service Pack 1 или более поздней версии;
  • Windows Server 2003 R2 (x86 или x64) или более поздней версии;
  • Windows Server 2008 (x86 и x64).

После того как мы ознакомились с основными новинками в Visual Studio 2008, давайте перейдем к деталям. Начнем с новинок в языках программирования — С# 3.0 и Visual Basic .NET 9.0.

Новинки в языках программирования

Знакомство с ключевыми новинками в Microsoft Visual Studio 2008 начнем с языков программирования, а именно с новых версий C# — C# 3.0 и Visual Basic .NET — VB 9.0, которые пополнились рядом синтаксических расширений и поддержкой технологии LINQ.

При работе над новой версией языка C# его создатели ставили перед собой следующие задачи: обеспечить на уровне языка интеграцию механизмов работы с объектами, реляционными данными и XML, а также добавить в язык ряд новых программных конструкций и при этом сделать его полностью совместимым с предыдущими версиями. Команда, отвечающая за развитие языка Visual Basic, решала схожие задачи: упростить механизмы запросов к данным, включить поддержку на уровне языка таких операций, как запрос к данным и их преобразование, унифицировать механизмы запросов к объектам, реляционным данным и данным в формате XML. Помимо этого в новую версию Visual Basic были встроены расширенные механизмы работы с XML, включая поддержку документов без схемы, возможность построения XML-документов и упрощенный доступ к их элементам.

Таким образом, интеграция и унификация механизмов запросов к объектам, реляционным данным и данным в формате XML вылились в технологию LINQ. Об этом механизме мы поговорим чуть позже, а сейчас обратим внимание на синтаксические расширения, появившиеся в новых версиях языков C# и Visual Basic .NET.

C# 3.0

Начнем с C# 3.0. Расширения, появившиеся в этой версии языка C#, приведены в табл. 3.

Таблица 3. Расширения языка C# 3.0

Расширение

Описание

Автоматическое создание методов для свойств объектов

Используется для автоматизации процесса создания свойств со стандартными функциями

Типизация локальных переменных

Позволяет определить тип локальной переменной по выражению, которое применяется для ее инициализации

Типизация массивов

Форма создания и инициализации массивов, в которой тип элемента определяется по выражению, используемому для его инициализации

Методы-расширения

Способ расширения существующих типов, а также типов, создаваемых пользователями

Лямбда-выражения

Расширение механизмов анонимных методов, которое существенно упрощает автоматическое определение типов и преобразование
их как в делегаты, так и в деревья выражений

Деревья выражений

Механизм поддержки лямбда-выражений, позволяющий представлять их в виде данных (деревьев выражений), а не кода (делегатов)

Инициализаторы объектов
и коллекций

Позволяют задавать значения одного или более полей или свойств вновь созданных объектов и объединять в одном шаге создание и инициализацию

Запросы

Интегрированный в язык синтаксис запросов, схожих с языком запросов к реляционным и иерархическим данным типа SQL и XQuery

Анонимные типы

Типы, которые автоматически создаются на основе инициализаторов объектов

Рассмотрим некоторые из этих расширений более подробно.

Автоматическое создание методов для свойств объектов

Методы доступа к свойствами объектов — get и set — часто имеют очень простую реализацию и служат для получения значения соответствующего поля внутри объекта (get) или присвоения этому полю нового значения (set). Создание свойств со стандартными методами доступа может существенно упростить написание кода и сделать его более понятным, так как в этом случае компилятор C# автоматически генерирует весь необходимый код. Рассмотрим следующий пример. Пусть у нас есть класс Point, содержащий два свойства:

 

public class Point

{

private int _x;

private int _y;

   public int X { get { return _x; } set { _x = value; } }

public int Y { get { return _y; } set { _y = value; } }

}

Для упрощения описания этого класса мы можем воспользоваться автоматическим созданием свойств. В этом случае описание класса Point будет выглядеть так:

public class Point

{

public int X {get ; set ;}

public int Y {get ; set ;}

}

 

Поскольку теперь компилятор берет на себя всю работу по реализации методов get и set, мы можем инициализировать наш объект как обычно:

 

GroundZero p = new Point();

p.X = 0;

p.Y = 0;

 

Если мы переопределим метод ToString() для нашего объекта следующим образом:

 

public override string ToString()

{

return X + «;» + Y;

}

 

то сможем воспользоваться методом WriteLine() для вывода содержимого полей объекта на экран консоли:

 

Console.WriteLine(c);

 

Создание свойств описанным выше методом требует, чтобы у свойств были методы доступа get и set, но если мы захотим добавить собственные методы, то можем воспользоваться описанным далее подходом.

Предположим, что у нас есть класс Customer, описанный следующим образом:

 

public class Customer

{

public string Name { get; set; }

public string City { get; set; }

   public override string ToString()

{

return Name + “\t” + City;

}

}

 

Теперь допустим, что мы хотим добавить еще одно свойство, которое вне класса будет доступно только для чтения. Метод автоматического создания свойств позволяет решить эту задачу путем использования модификатора — в нашем примере это будет модификатор private для метода set:

 

public class Customer

{

public int CustomerID { get; private set; }

public string Name { get; set; }

public string City { get; set; }

}

Инициализация объектов и коллекций

Следующее расширение синтаксиса языка C#, которое мы рассмотрим, связано с упрощением инициализации объектов и коллекций. При объявлении объекта или коллекции в C# возможно применение так называемого инициализатора, который будет задавать начальные значения членов вновь создаваемых объектов или коллекций. Новый синтаксис позволяет объединить в одном шаге и создание, и инициализацию объекта или коллекции. Рассмотрим пример использования инциализатора для объекта. Пусть у нас есть класс Point, содержащий два свойства:

 

public class Point

{

private int _x;

private int _y;

   public int X { get { return _x; } set { _x = value; } }

public int Y { get { return _y; } set { _y = value; } }

}

 

Инициализатор объекта состоит из последовательности инициализаторов членов класса, заключенных в фигурные скобки { } и разделенных запятыми. Каждый инициализатор члена класса присваивает значение полю или свойству объекта. Для нашего класса Point-инициализация с использованием нового синтаксиса будет выглядеть так:

 

Point p = new Point { X = 3, Y = 99 };

 

Такой компактный синтаксис инициализации объекта семантически эквивалентен вызову конструктора класса и присвоению значения каждому члену класса.

Отметим, что при таком способе инициализации необязательно указывать в списке все поля объекта — неуказанные поля получат значения, присваиваемые по умолчанию.

В языке C# объекты, которые реализуют интерфейс System.Collections.Generic.IEnumerable<T> и имеют метод Add(), могут быть инициализированы с помощью инициализатора коллекций. Применяя наш класс Point, мы можем создать коллекцию точек, описывающую какую-то геометрическую фигуру:

 

List<Point> Square = new List<Point>

{

new Point { X=0, Y=5 },

new Point { X=5, Y=5 },

new Point { X=5, Y=0 },

new Point { X=0, Y=0 }

};

Типизация переменных и массивов

Следующее расширение синтаксиса языка C#, которое мы рассмотрим, связано с типизацией переменных и массивов и позволяет определить тип локальной переменной или элемента массива по выражению, которое используется для инициализации. Для задания переменных, тип которых может быть определен компилятором автоматически, применяется конструкция var, а для использования аналогичных возможностей для массивов — синтаксис new[]{…} — обратите внимание на отсутствие указания типа. Сначала приведем «стандартный» синтаксис, который мы использовали для задания и инициализации переменных и массивов в предыдущих версиях языка:

 

int i = 43;

 string s = «...This is only a test...»;

 int[] numbers = new int[] { 4, 9, 16};

 

Применяя механизмы типизации для переменных и массивов, мы можем инициализировать переменные и массивы более простым способом:

 

var i = 43;

var s = “...This is only a test...”;

var numbers = new [] { 4, 9, 16 };

 

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

 

var x; // Ошибка: тип не определен

x = new int[] { 1, 2, 3 };

 

Также мы всегда должны использовать синтаксис new[]{…} при создании инициализируемых массивов — при выполнении следующего кода мы получим ошибку:

 

var x = {1, 2, 3};

 

для исправления которой код нужно переписать следующим образом:

 

var x = new [] {1, 2, 3};

 

Применяя конструкцию var, мы можем упростить код некоторых комплексных выражений. Например, вместо использования в механизме итерации foreach четкого указания типа, как показано в следующем примере:

 

 Console.WriteLine(«Customers»);

 foreach (Customer c in customers)

Console.WriteLine(c);

 

можно применять конструкцию var:

Console.WriteLine(“Customers:”);

foreach (var c in customers)

Console.WriteLine(c);

Методы-расширения

Методы-расширения представляют собой способ расширения существующих типов, а также типов, создаваемых пользователями. Используя этот способ, разработчики могут добавлять к существующим типам новые методы, которые будут вызываться с применением стандартного синтаксиса. Методы-расширения — это статические методы, объявляемые с помощью ключевого слова this в качестве модификатора первого параметра метода. Приведем следующий пример. Предположим, нам нужна функция сравнения двух объектов типа Customer. В C# 2.0 мы могли бы написать следующий код:

 

public static class Extensions

{

public static bool Compare(Customer customer1, Customer

customer2)

{

if (customer1.Name == customer2.Name &&

customer1.City == customer2.City )

{

return true;

}

       return false;

}

}

 

Вызов этого метода может выглядеть так:

 

foreach (var c in customers)

{

if (Extensions.Compare(newCusomter, c))

{

Console.WriteLine(«Already in the list»);

return;

}

}

 

В C# 3.0 можно реализовать ту же функциональность с помощью метода-расширения, которое будет вызываться в контексте объекта с использованием стандартного синтаксиса. Добавим ключевое слово this в качестве модификатора первого параметра метода Compare();

 

public static class Extensions

{

public static bool Compare(this Customer customer1, Customer

customer2)

{

...

}

}

 

Тогда наш код проверки двух объектов будет выглядеть следующим образом:

 

foreach (var c in customers)

{

   if (newOrder.Compare(c))

{

Console.WriteLine(“Already in the list”);

return;

}

 

Запомните следующее простое правило: методы-расширения доступны только в том случае, когда они объявлены в статическом классе и находятся в области видимости соответствующего пространства имен. Эти методы будут доступны в качестве дополнительных методов для типов, указанных в качестве первого параметра метода.

Методы-расширения могут быть добавлены к любому типу, включая такие встроенные типы, как List<T> и Dictionary<K, V>. Рассмотрим пример расширения функциональности стандартного типа List<T> — добавим к нему метод Append(), который будет объединять два элемента типа List<T> в один:

 

public static class Extensions

{

public static List<T> Append<T>(this List<T> a, List<T> b)

{

var newList = new List<T>(a);

newList.AddRange(b);

return newList;

}          

...

}

 

Вызов нового метода-расширения для стандартного типа может выглядеть так:

 

{

...

var addedCustomers = new List<Customer>

{

new Customer { Name = “Paolo Accorti”, City = “Torino” },

new Customer { Name = “Diego Roel”,   City = “Madrid” }

};

   customers.Append(addedCustomers);

...

}

 

Методы-расширения предоставляют в распоряжение разработчиков элегантный способ расширения функциональности типов таким образом, что добавленные функции становятся частью типа. Используя методы-расширения, можно добавлять новую функциональность к уже откомпилированным классам, включая классы, созданные пользователем, и стандартные классы .NET Framework.

Лямбда-выражения

Лямбда-выражения — это расширение механизмов анонимных методов, которое существенно упрощает автоматическое определение типов и преобразование как в делегаты, так и в деревья выражений.

В C# 2.0 появились анонимные методы, позволяющие вставлять блоки кода в тех местах, где возможно использование делегатов. Например:

 

var innerPoints = points.FindAll(delegate(Point p)

{ return (p.X > 0 && p.Y > 0); });

 

Метод FindAll() ожидает параметр в виде делегата. В нашем примере делегат определяет, являются ли координаты x и y положительными, то есть относится ли точка с заданными координатами к первому квадранту картезианской поверхности.

В C# 3.0 появились лямбда-выражения, позволяющие использовать более простой синтаксис для написания анонимных методов. В результате предыдущий пример можно переписать так:

 

var innerPoints = points.FindAll( p => p.X > 0 && p.Y > 0);

 

Лямбда-выражение пишется как список параметров, за которым следует символ =>, а за ним — код самого выражения. Например:

 

(int x) => { return x + 1; }

 

Параметры лямбда-выражения могут быть непосредственно или опосредованно типизированы:

 

(int x) => x + 1       

 

В списке опосредованно типизированных параметров типы параметров получаются из контекста, в котором применяется данное лямбда-выражение. Помимо этого если в лямбда-выражении задан один типизированный параметр, то список параметров можно не заключать в скобки:

 

x => x + 1

(x,y) => x * y;

 

Предположим, мы хотим найти в списке объектов Customer все объекты с определенным значением поля City. Для этого мы можем использовать метод FindAll() класса List<T>. Напишем метод FindCustomersByCity(), в котором будем применять анонимные методы и делегаты, используя синтаксис C# 2.0:

 

public static List<Customer> FindCustomersByCity(

List<Customer> customers,

string city)

{

return customers.FindAll(

delegate(Customer c){

return c.City == city;

});

}

 

Вызов этого метода будет выглядеть следующим образом:

 

{

var customers = CreateCustomers();

   foreach (var c in FindCustomersByCity(customers, “London”))

Console.WriteLine(c);

}

 

Теперь воспользуемся возможностями C# 3.0 и заменим анонимный метод эквивалентным лямбда-выражением:

 

public static List<Customer> FindCustomersByCity(

List<Customer> customers, string city)

{

return customers.FindAll(c => c.City == city);

}

 

Как было показано ранее, использование лямбда-выражений в некоторых случаях упрощает написание кода. В приведенном выше примере список параметров состоит из нетипизированного параметра ‘c’, и, таким образом, явного указания типа не требуется. В качестве альтернативы мы можем написать следующий код:

 

return customers.FindAll ((Customer c) => c.City == city);

 

На этом мы заканчиваем рассмотрение новых возможностей, появившихся в C# 3.0. Желающие более подробно узнать обо всех новинках могут обратиться к спецификации C# 3.0, которая доступна на сайте MSDN, а также к соответствующим разделам документации по .NET Framework 3.0 SDK и Visual Studio 2008. Теперь посмотрим, что нового появилось в Visual Basic .NET 9.0.

Visual Basic .NET 9.0

Как мы отметили ранее, задача новой версии VB .NET — упростить механизмы запросов к данным, включить поддержку на уровне языка таких операций, как запрос к данным и их преобразование, унифицировать механизмы запросов к объектам, реляционным данным и данным в формате XML. Помимо этого в новую версию Visual Basic встроены расширенные механизмы работы с XML, включая поддержку документов без схемы, возможность построения XML-документов и упрощенный доступ к элементам таких документов.

В качестве примера будем использовать класс Country, который будет содержать информацию о стране — название, площадь и численность населения:

 

Class Country

Public Property Name As String

Public Property Area As Long

Public Property Population As Integer

End Class

Типизация локальных переменных

Начнем наше знакомство с новинками в Visual Basic 9.0, касающимися типизации локальных переменных. Как мы помним из нашего обсуждения языка C# 3.0, этот механизм позволяет определить тип локальной переменной по выражению, которое применяется для ее инициализации. Например, компилятор может легко определить типы для следующих локальных переменных:

 

Dim Name = «Monaco»

Dim Area = 1.9

Dim Population = 31719

Dim country = New Country With { .Name = “Monaco”, …}

 

Приведенный выше код является эквивалентом следующей группы объявлений:

 

Dim Name As String = «Monaco»

Dim Area As Float = 1.9

Dim Population As Integer = 31719

Dim country As Country = New Country With { .Name = «Monaco», …}

 

Поскольку типы локальных переменных определяются компилятором по выражению, которое используется для их инициализации (это возможно благодаря новой опции Option Infer On, включенной по умолчанию для всех новых проектов), независимо от значения опции Option Strict доступ к таким переменным всегда осуществляется на основе раннего связывания. Для включения позднего связывания всегда нужно указывать тип переменных как Object, например:

 

Dim country As Object = New Country With { .Name = “Monaco”, … }

 

Определение типов данных при их инициализации предотвращает применение позднего связывания и позволяет реализовать такие расширения, как связывание с новыми типами данных, например XML, — мы обсудим эти возможности далее.

Инициализация массивов и объектов

В Visual Basic ключевое слово With упрощает доступ к нескольким членам агрегатного типа данных без необходимости в указании этого типа для каждого члена. Внутри блока With выражение, используемое для доступа к члену типа, начинается с точки, и при его обработке компилятором такое выражение разворачивается в полное, как если бы слева от точки было указано название типа. Например:

 

Dim palau As New Country()

With palau

.Name = “Monaco”

.Area = 1.9

.Population = 31719

End With

 

Новые инициализаторы объектов в Visual Basic 9.0 позволяют существенно упростить создание и инициализацию объектов, объединив их в один шаг:

 

Dim palau New Country With {

.Name = «Monaco», _

.Area = 1.9, _

.Population = 31719 _

}

 

Как показано выше, инициализаторы объектов достаточно удобны для создания коллекций комплексных объектов. Массивы могут быть инициализированы, а типы их элементов автоматически определены с помощью инициализаторов массивов. Например, если есть класс City, описывающий город:

 

Class City

Public Property Name As String

Public Property Country As String

Public Property Longitude As Long

Public Property Latitude As Long

End Class

 

то мы можем создать массив, описывающий столицы некоторых стран, следующим образом:

 

Dim Capitals = { _

New City With { _

.Name = “Antanarivo”, _

.Country = “Madagascar”, _

.Longitude = 47.4, _

.Latitude = -18.6 }, _

New City With { _

.Name = “Belmopan”, _

.Country = “Belize”, _

.Longitude = -88.5, _

.Latitude = 17.1 }, _

New City With { _

.Name = “Monaco”, _

.Country = “Monaco”, _

.Longitude = 7.2, _

.Latitude = 43.7 }, _

New City With { _

.Country = “Palau”,

.Name = “Koror”, _

.Longitude = 135, _

.Latitude = 8 } _

}

«Пустые» типы

В новой версии Visual Basic появилась поддержка «пустых» типов, реализованная через стандартный тип данных Nullable(Of T As Structure), имеющийся в .NET Framework 2.0. Такая поддержка необходима для обеспечения более удобной интеграции с данными, получаемыми из баз данных, и полноценной реализации механизма LINQ. Используя такой тип данных, можно объявлять «пустые» версии переменных таких типов, как Integer, Boolean, Date и т.п.

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

 

Partial Class Country

Public Property Independence As Date?

End Class

 

День независимости Республики Палау — 1 октября 1994 года, но Британские Виргинские острова являются частью Великобритании, поэтому для них день независимости будет иметь значение Nothing:

 

Dim palau = _

New Country With { _

.Name = «Palau», _

.Area = 458, _

.Population = 16952, _

.Independence = #10/1/1994# }

Dim virginIslands = _

New Country With { _

.Name = «Virgin Islands», _

.Area = 150, _

.Population = 13195, _

.Independence = Nothing }

 

В Visual Basic 9.0 поддерживается следующее правило: если один из операндов арифметической операции, операции сравнения, логической или бинарной операции, операции сдвига, работы со строками или типизации имеет значение Nothing, результат операции будет Nothing.

Поскольку поля объектов Palau.Independence и VirginIslands.Independence имеют тип Date?, компилятор использует описанный выше подход для следующего вычисления, так как при автоматическом определении типов обе локальные переменные — PLength и VILength — будут иметь тип TimeSpan?:

 

‘ 3980.00:00:00

Dim pLength = #8/24/2005# - Palau.Independence

 

Значение переменной PLength будет 3980.00:00:00, поскольку оба операнда операции имеют типы, отличные от Nothing. Однако, поскольку поле VirginIslands.Independence имеет значение Nothing, результат опять будет иметь тип TimeSpan?, но значение переменной VILength будет Nothing, так как действует описанное выше правило:

 

Dim vILength = #8/24/2005# - virginIslands.Independence ‘ Nothing

 

Как и в языке SQL, в операторах If и While значение Nothing интерпретируется как False, и в следующем фрагменте кода будет задействована ветвь Else:

 

If vILength < TimeSpan.FromDays(10000)

Else

End If

Упрощенные делегаты

При создании делегатов в Visual Basic 8.0, используя ключевые слова AddressOf или Handles, один из методов, обеспечивающих связывание с идентификатором делегата, должен иметь точную сигнатуру типа делегата. В приведенном далее примере сигнатура метода OnClick должна точно соответствовать сигнатуре делегата обработчика события Delegate Sub EventHandler(sender As Object, e As EventArgs), который объявлен для класса Button:

 

Dim WithEvents btn As New Button()

Sub OnClick(sender As Object, e As EventArgs) Handles B.Click

MessageBox.Show(“Hello World from” & btn.Text)

End Sub

 

Но при вызове функций и подпрограмм, не являющихся делегатами, Visual Basic не требует, чтобы аргументы в точности соответствовали вызываемым методам. Как показано далее, мы можем вызвать подпрограмму OnClick, используя аргументы типа Button и MouseEventArgs, которые являются подтипами формальных параметров Object и EventArgs соответственно:

 

Dim m As New MouseEventArgs(MouseButtons.Left, 2, 47, 11,0)

OnClick(btn, m)

 

Предположим, мы можем определить подпрограмму — назовем ее RelaxedOnClick, — которая получает два параметра типа Object, и вызвать ее с аргументами типа Object и EventArgs:

 

Sub RelaxedOnClick(sender As Object, e As Object) Handles btn.Click

MessageBox.Show(“Hello World from” & btn.Text))

End Sub

Dim e As EventArgs = m

Dim s As Object = btn

RelaxedOnClick(btn,e)

 

В Visual Basic 9.0 связь делегатов упрощена и поддерживается соответствие вызываемому методу. Таким образом, если появляется возможность вызова функции или подпрограммы с параметрами и возвращаемыми типами, которые в точности соответствуют делегату, то мы можем связать эту функцию или подпрограмму с делегатом. Другими словами, связь с делегатом и его определением следует той же логике перегрузки, что и вызов обычных методов.

В Visual Basic 9.0 мы можем связать подпрограмму RelaxedOnClick, которая имеет два аргумента типа Object, с событием Click класса Button:

 

Sub RelaxedOnClick(sender As Object, e As Object) Handles btn.Click

MessageBox.Show((“Hello World from” & btn.Text)

End Sub

 

В данном случае два аргумента обработчика события — sender и EventArgs — особого значения не имеют. Вместо этого обработчик обращается непосредственно к компоненту, для которого зарегистрировано событие, и игнорирует эти аргументы. Для поддержки такого сценария делегаты могут вообще не использовать аргументов — в том случае, если не возникает неразрешимых противоречий. Другими словами, можно написать следующий код:

 

Sub RelaxedOnClick Handles btn.Click

MessageBox.Show(“Hello World from” & btn.Text)

End Sub

 

Такое упрощение работы с делегатами распространяется и на конструирование делегатов с помощью ключевого слова AddressOf, и на выражения, создающие делегаты, даже в тех случаях, когда применяется позднее связывание:

 

Dim F As EventHandler = AddressOf RelaxedOnClick

Dim G As New EventHandler(AddressOf btn.Click)

 

На этом мы завершаем рассмотрение новшеств в Visual Basic .NET 9.0, касающихся языков программирования. Желающие более подробно ознакомиться со всеми новинками могут обратиться к спецификации языка, которая доступна на сайте MSDN, а также к соответствующим разделам документации по .NET Framework 3.0 SDK и Visual Studio 2008.

 

В начало В начало

КомпьютерПресс 2'2008

Наш канал на Youtube

1999 1 2 3 4 5 6 7 8 9 10 11 12
2000 1 2 3 4 5 6 7 8 9 10 11 12
2001 1 2 3 4 5 6 7 8 9 10 11 12
2002 1 2 3 4 5 6 7 8 9 10 11 12
2003 1 2 3 4 5 6 7 8 9 10 11 12
2004 1 2 3 4 5 6 7 8 9 10 11 12
2005 1 2 3 4 5 6 7 8 9 10 11 12
2006 1 2 3 4 5 6 7 8 9 10 11 12
2007 1 2 3 4 5 6 7 8 9 10 11 12
2008 1 2 3 4 5 6 7 8 9 10 11 12
2009 1 2 3 4 5 6 7 8 9 10 11 12
2010 1 2 3 4 5 6 7 8 9 10 11 12
2011 1 2 3 4 5 6 7 8 9 10 11 12
2012 1 2 3 4 5 6 7 8 9 10 11 12
2013 1 2 3 4 5 6 7 8 9 10 11 12
Популярные статьи
КомпьютерПресс использует