Опубликован: 13.10.2008 | Доступ: свободный | Студентов: 1593 / 172 | Оценка: 4.22 / 3.70 | Длительность: 09:12:00
ISBN: 978-5-9963-0003-7
Лекция 4:

С# 3.0

< Лекция 3 || Лекция 4: 12 || Лекция 5 >
Аннотация: Особенности: неявная типизация, расширяющие методы, инициализаторы и анонимные типы, интеграция способов представления данных, реализация возможностей XSD, XQuery, XSLT, XPath и других средств работы с языком представления данных XML

Обзор C# 3.0

C# 3.0 ("C# Orcas") представляет собой расширение C# 2.0, разработанное для создания высокоуровневых библиотек классов с использованием подходов функционального программирования. C# 3.0 позволяет создавать API, поддерживающие запросы к реляционным базам данных и XML. C# 3.0 включает следующие расширения:

  • Неявно типизированные локальные переменные.То есть тип локальной переменной может быть получен из выражения, инициализирующего эту переменную.
  • Неявно типизированные массивы.
  • Расширяющие методы.Они позволяют добавлять методы к уже существующим типам данных.
  • Лямбда-выражения.В C# 3.0 представляют собой развитие анонимных методов.
  • Инициализаторы объектов.Упрощают создание и инициализацию объектов.
  • Анонимные типы.Типы-кортежи, которые определяются на основе инициализаторов объектов.
  • Выражения, содержащие запросы.В C# добавлены выражения, аналогичные выражениям на языках запросов SQL и XQuery.
  • Деревья выражений.Позволяют представить лямбда-выражения в виде данных.

Спецификации C# 1.2 и 2.0 гораздо объемнее (более 100 стр.) по сравнению с C# 3.0, так как содержат описания основ языка, и доступны по ссылке http://msdn.microsoft.com/vcsharp/language.

Неявно типизированные локальные переменные

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

var i = 5
var numbers = new int[] {1, 2, 3}

Тип var не был определен в коде, при этом объявления эквивалентны следующему:

int i = 5
int[] numbers = new int[] {1, 2, 3}

Для неявно типизированных переменных существуют следующие ограничения:

  • объявление переменной должно включать инициализатор;
  • инициализатор должен быть выражением и не должен быть объектом или инициализатором коллекции. (Объект и коллекцию можно включить в выражение с new.)
  • тип инициализирующего выражения на момент компиляции не может быть null-типом.

Если объявление локальной переменной содержит несколько вложенных объявлений (например, при создании массива), все инициализаторы должны иметь один тип на момент компиляции.

Примеры нарушения ограничений:

var x;             // Error, no initializer to infer type from
var y = {1, 2, 3}; // Error, collection initializer not permitted 
var z = null;      // Error, null type not permitted

Если объявляется локальная переменная типа var, который был определен в коде, — используется определенный в коде тип и генерируется предупреждение (warning).

Неявно типизированные локальные переменные можно использовать в конструкциях for и foreach.

int[] numbers = { 1, 3, 5, 7, 9 }
foreach (var n in numbers) Console.WriteLine(n)

Неявно типизированные массивы

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

var a = new[] { 1, 10, 100, 1000 };    // int[] 
var d = new[] { 1, "one", 2, "two" };  // Error

В последнем случае происходит ошибка компиляции, так как невозможно неявно преобразовать int в string и наоборот.

Зачем нужна неявная типизация?

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

Кроме того, возможности неявной типизации могут быть полезны программистам, работающим на языках типа php, где возможности неявного определения типа были заложены изначально. Они могут получить преимущества управляемого программирования, перейдя на C# и сохраняя при этом привычный стиль программирования.

Однако возможности неявной типизации, без сомнения, могут служить источником дополнительных ошибок и делают код менее понятным.

Расширяющие методы

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

Расширяющие методы содержат первым параметром переменную того типа, который данный метод расширяет. Перед типом стоит ключевое слово this. Например:

Namespace Acme.Utilities 
{
 public static class Extensions 
 {
  public static int ToInt32(this string s) 
  {
   return Int32.Parse(s) 
  }
  
  public static T[] Slice<T>(this T[] source, int index, int count) 
  {
   if (index < 0 || count < 0 || source.Length - index < count)
      throw new ArgumentException() 
      T[] result = new T[count] 
      Array.Copy(source, index, result, 0, count) 
      return result 
  }
 }
}

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

using Acme.Utilities
string s = "1234"
int i = s.ToInt32();   // То же, что Extensions.ToInt32(s)
int[] digits = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
int[] a = digits.Slice(4, 3); //То же,что Extensions.Slice(digits, 4, 3)

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

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

C# 2.0 поддерживал анонимные методы, позволяющие писать блоки кода вместо параметров-делегатов. Анонимные методы предоставляют значительную часть возможностей для функционального программирования, но при этом обладают достаточно сложным синтаксисом. Лямбда-выражения предоставляют более краткий функциональный синтаксис написания анонимных методов.

< Лекция 3 || Лекция 4: 12 || Лекция 5 >
Вячеслав Кузнецов
Вячеслав Кузнецов

Здравствуйте.

Как оплатить курс?