Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
Неявная типизация локальных переменных
В главе 3 вы узнали о ключевом слове
var
static void DeclareImplicitVars()
{
// Неявно типизированные локальные переменные.
var myInt = 0;
var myBool = true;
var myString = "Time, marches on...";
// Вывести имена лежащих в основе типов.
Console.WriteLine("myInt is a: {0}", myInt.GetType().Name);
Console.WriteLine("myBool is a: {0}",
myBool.GetType().Name);
Console.WriteLine("myString is a: {0}",
myString.GetType().Name);
}
Это языковое средство удобно и зачастую обязательно, когда применяется LINQ. Как вы увидите на протяжении главы, многие запросы LINQ возвращают последовательность типов данных, которые не будут известны вплоть до этапа компиляции. Учитывая, что лежащий в основе тип данных не известен до того, как приложение скомпилируется, вполне очевидно, что явно объявить такую переменную невозможно!
Синтаксис инициализации объектов и коллекций
В главе 5 объяснялась роль синтаксиса инициализации объектов, который позволяет создавать переменную типа класса или структуры и устанавливать любое количество ее открытых свойств за один прием. В результате получается компактный (и по-прежнему легко читаемый) синтаксис, который может использоваться для подготовки объектов к потреблению. Также вспомните из главы 10, что язык C# поддерживает похожий синтаксис инициализации коллекций объектов. Взгляните на следующий фрагмент кода, где синтаксис инициализации коллекций применяется для наполнения
List<T>
Rectangle
Point
List<Rectangle> myListOfRects = new List<Rectangle>
{
new Rectangle {TopLeft = new Point { X = 10, Y = 10 },
BottomRight = new Point { X = 200, Y = 200}},
new Rectangle {TopLeft = new Point { X = 2, Y = 2 },
BottomRight = new Point { X = 100, Y = 100}},
new Rectangle {TopLeft = new Point { X = 5, Y = 5 },
BottomRight = new Point { X = 90, Y = 75}}
};
Несмотря на то что использовать синтаксис инициализации коллекций или объектов совершенно не обязательно, с его помощью можно получить более компактную кодовую базу. Кроме того, этот синтаксис в сочетании с неявной типизацией локальных переменных позволяет объявлять анонимный тип, что удобно при создании проекций LINQ. О проекциях LINQ речь пойдет позже в главе.
Лямбда-выражения
Лямбда-операция C# (
=>
<i>АргументыДляОбработки =></i>
<i>{</i>
<i> ОбрабатывающиеОператоры</i>
<i>}</i>
В главе 12 было показано, как взаимодействовать с методом
FindAll()
List<T>
Predicate<T>
static void LambdaExpressionSyntax()
{
// Создать список целочисленных значений.
List<int> list = new List<int>();
list.AddRange(new int[] { 20, 1, 4, 8, 9, 44 });
// Теперь использовать лямбда-выражение С#.
List<int> evenNumbers = list.FindAll(i => (i % 2) == 0);
// Вывести четные числа
Console.WriteLine("Here are your even numbers:");
foreach (int evenNumber in evenNumbers)
{
Console.Write("{0}t", evenNumber);
}
Console.WriteLine();
}
Лямбда-выражения будут удобны при работе с объектной моделью, лежащей в основе LINQ. Как вы вскоре выясните, операции запросов LINQ в C# — просто сокращенная запись для вызова методов класса по имени
System.Linq.Enumerable
Funс<>
Расширяющие методы
Расширяющие методы C# позволяют оснащать существующие классы новой функциональностью без необходимости в создании подклассов. Кроме того, расширяющие методы дают возможность добавлять новую функциональность к запечатанным классам и структурам, которые в принципе не допускают построения подклассов. Вспомните из главы 11, что когда создается расширяющий метод, первый его параметр снабжается ключевым словом
this
static