Секреты LINQ. Автогенерируемые свойства. Инициализаторы объектов и коллекций, страница 2

Описатель контекстный указывает на то, что смысл слова зависит от контекста. Например, слово where в применении к универсальному (generic) типу задает ограничение на возможные типы параметра шаблона, а в запросе LINQ это же слово задает условие отбора (фильтр отбора) данных.

Редко используемый описатель ?

Некоторые описатели типа могут сопровождаться знаком вопроса. Так объявляются Nullable-типы. Например.

int? i = null;

Это вполне законное с точки зрения синтаксиса C# объявление (и присвоение). Значение null может быть присвоено переменной любого из примитивных (value) типов, если в объявлении присутствует знак вопроса. Этот знак не является ключевым словом. Скорее, это модификатор типа. Думаю, что вы не встречали также операцию ?? (два следующие подряд знака вопроса). Эта операция используется для проверки на null. Выполните следующий фрагмент и вы поймете, как работает операция ??.

string

s = null,

test = s ?? "String s == null";

Console.WriteLine (test);

s = "Set of C# Keywords";

test = s ?? "String s == null";

Console.WriteLine (test);

Список расширений языка C#

Перед тем, как приступить к составлению запросов LINQ, необходимо познакомиться с расширениями языка C#, на которых они основаны. Сначала перечислим их, а затем познакомимся более подробно.

¨  Неявно типизированные переменные (local variable type inference). Теперь можно писать: var s = "Hi"; и компилятор автоматически превратит это в string s = "Hi";

¨  Автоматически реализуемые свойства (auto-implemented properties). В предыдущем курcе мы часто добавляли в классы пары вида {переменная, свойство} таким образом:

decimal salary;

public decimal Salary

{

get { return salary; }

set { salary = value; }

}

Теперь вы можете пользоваться сокращенной записью. Ранее такая запись допускалась только при объявлении интерфейса.

public decimal Salary { get; set; }

¨  Инициализаторы объектов и коллекций (object initializers). Предположим, что вы объявили класс:

public class Person

{

public string Name { get; set; }

public DateTime Birth { get; set; }

public decimal Salary { get; set; }

}

Теперь вы можете создать объект класса Person, используя только его свойства:

Person alex = new Person(){ Name = "Alex", Birth = new DateTime(1994, 2, 26), Salary = 10000m };

Заметьте, в классе Person нет ни одного конструктора. Автоматически сгенерированный конструктор без параметров пользуется автоматически реализуемыми свойствами.

¨  Generic-делегаты, generic-классы и generic-методы. Наиболее точно передает смысл термина generic прилагательное универсальный. Например, generic-класс — это универсальный класс, настраиваемый на определенный тип данных с помощью параметра. Слово шаблон (template), которое используется в языке С++, лишь приближенно соответствует термину generic. Мы вскоре рассмотрим эту технику.

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

¨  Возможность расширения существующих типов с помощью статических методов статических классов.

¨  Анонимные типы, или проецирование на произвольные структуры.

¨  Каркас языка интегрированных запросов .NET (LINQ). Мы рассмотрим его позже.

¨  Встроенная поддержка ASP.NET AJAX (Asynchronous JavaScript and XML). Эта технология позволяет при просмотре Web-страницы незаметно для пользователя (асинхронно) обращаться к серверу. Обращение происходит в рамках другого потока, при его завершении страница не перегружается полностью, а частично дополняется или видоизменяется с помощью внедренного кода на языке JavaScript.

Теперь более подробно рассмотрим описанные нововведения.

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

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

var s = "This is a string of characters";

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