Язык программирования C#9 и платформа .NET5
TesterMethod(null);В языке C# имеется маркер
-условной операции (знак вопроса, находящийся после типа переменной, но перед операцией доступа к члену), который позволяет упростить представленную ранее проверку на предметnull. Вместо явного условного оператора, проверяющего на неравенство значениюnull, теперь можно написать такой код:nullstatic void TesterMethod(string[] args){// Мы должны проверять на предмет null перед доступом к данным массива!Console.WriteLine($"You sent me {args?.Length} arguments.");}В этом случае условный оператор не применяется. Взамен к переменной массива
в качестве суффикса добавлена операцияstring. Если переменная?равнаargs, тогда обращение к свойствуnullне приведет к ошибке во время выполнения. Чтобы вывести действительное значение, можно было бы воспользоваться операцией объединения сLengthи установить стандартное значение:nullConsole.WriteLine($"You sent me {args?.Length ?? 0} arguments.");Существуют дополнительные области написания кода, в которых
-условная операция окажется очень удобной, особенно при работе с делегатами и событиями. Данные темы раскрываются позже в книге (см. главу 12) и вы встретите еще много примеров.nullПонятие кортежей (нововведение и обновление в версии 7.0)
В завершение главы мы исследуем роль кортежей, используя проект консольного приложения по имени
. Как упоминалось ранее в главе, одна из целей применения параметровFunWithTuples— получение более одного значения из вызова метода. Еще один способ предусматривает использование конструкции под названием кортежи.outКортежи, которые являются легковесными структурами данных, содержащими множество полей, фактически появились в версии C# 6, но применяться могли в крайне ограниченной манере. Кроме того, в их реализации C# 6 существовала значительная проблема: каждое поле было реализовано как ссылочный тип, что потенциально порождало проблемы с памятью и/или производительностью (из-за упаковки/распаковки).
В версии C# 7 кортежи вместо ссылочных типов используют новый тип данных
, сберегая значительных объем памяти. Тип данныхValueTupleсоздает разные структуры на основе количества свойств для кортежа. Кроме того, в C# 7 каждому свойству кортежа можно назначать специфическое имя (подобно переменным), что значительно повышает удобство работы с ними.ValueTupleОтносительно кортежей важно отметить два момента:
• поля не подвергаются проверке достоверности;
• определять собственные методы нельзя.
В действительности кортежи предназначены для того, чтобы служить легковесным механизмом передачи данных.
Начало работы с кортежами
Итак, достаточно теории, давайте напишем какой-нибудь код! Чтобы создать кортеж, просто повестите значения, подлежащие присваиванию, в круглые скобки:
("a", 5, "c")Обратите внимание, что все значения не обязаны относиться к тому же самому типу данных. Конструкция с круглыми скобками также применяется для присваивания кортежа переменной (или можно использовать ключевое слово
и тогда компилятор назначит типы данных самостоятельно). Показанные далее две строки кода делают одно и то же — присваивают предыдущий пример кортежа переменной. Переменнаяvarбудет кортежем с двумя свойствамиvaluesи одним свойствомstring.int(string, int, string) values = ("a", 5, "c");var values = ("a", 5, "c");По умолчанию компилятор назначает каждому свойству имя
, гдеItemXпредставляет позицию свойства в кортеже, начиная с 1. В предыдущем примере свойства именуются какX,Item1иItem2. Доступ к ним осуществляется следующим образом:Item3Console.WriteLine($"First item: {values.Item1}"); // Первый элементConsole.WriteLine($"Second item: {values.Item2}"); // Второй элементConsole.WriteLine($"Third item: {values.Item3}"); // Третий элементКроме того, к каждому свойству кортежа справа или слева можно добавить специфическое имя. Хотя назначение имен в обеих частях оператора не приводит к ошибке на этапе компиляции, имена в правой части игнорируются, а использоваться будут имена в левой части. Показанные ниже две строки кода демонстрируют установку имен в левой и правой частях оператора, давая тот же самый результат:
(string FirstLetter, int TheNumber, string SecondLetter)valuesWithNames = ("a", 5, "c");var valuesWithNames2 = (FirstLetter: "a", TheNumber: 5, SecondLetter: "c");Теперь доступ к свойствам кортежа возможен с применением имен полей, а также системы обозначений
:ItemXConsole.WriteLine($"First item: {valuesWithNames.FirstLetter}");Console.WriteLine($"Second item: {valuesWithNames.TheNumber}");Console.WriteLine($"Third item: {valuesWithNames.SecondLetter}");// Система обозначений ItemX по-прежнему работает!Console.WriteLine($"First item: {valuesWithNames.Item1}");Console.WriteLine($"Second item: {valuesWithNames.Item2}");Console.WriteLine($"Third item: {valuesWithNames.Item3}");