C Sharp

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

Шаблон:Не путать Шаблон:Другие значения термина

Шаблон:Карточка языка программирования C# (произносится си шарп) — объектно-ориентированный язык программирования общего назначения. Разработан в 19982001 годах группой инженеров компании Microsoft под руководством Андерса Хейлсберга и Скотта Вильтаумота<ref>Шаблон:Книга</ref> как язык разработки приложений для платформы Microsoft .NET Framework и .NET. Впоследствии был стандартизирован как ECMA-334 и ISO/IEC 23270.

C# относится к семье языков с C-подобным синтаксисом, из них его синтаксис наиболее близок к C++ и Java. Язык имеет статическую типизацию, поддерживает полиморфизм, перегрузку операторов (в том числе операторов явного и неявного приведения типа), делегаты, атрибуты, события, переменные, свойства, обобщённые типы и методы, итераторы, анонимные функции с поддержкой замыканий, LINQ, исключения, комментарии в формате XML.

Переняв многое от своих предшественников — языков C++, Delphi, Модула, Smalltalk и, в особенности, Java — С#, опираясь на практику их использования, исключает некоторые модели, зарекомендовавшие себя как проблематичные при разработке программных систем, например, C# в отличие от C++ не поддерживает множественное наследование классов (между тем допускается множественная реализация интерфейсов).

Особенности языка

С# разрабатывался как язык программирования прикладного уровня для CLR и, как таковой, зависит, прежде всего, от возможностей самой CLR. Это касается, прежде всего, системы типов С#, которая отражает BCL. Присутствие или отсутствие тех или иных выразительных особенностей языка диктуется тем, может ли конкретная языковая особенность быть транслирована в соответствующие конструкции CLR. Так, с развитием CLR от версии 1.1 к 2.0 значительно обогатился и сам C#; подобного взаимодействия следует ожидать и в дальнейшем (однако, эта закономерность была нарушена с выходом C# 3.0, представляющего собой расширения языка, не опирающиеся на расширения платформы .NET). CLR предоставляет С#, как и всем другим .NET-ориентированным языкам, многие возможности, которых лишены «классические» языки программирования. Например, сборка мусора не реализована в самом C#, а производится CLR для программ, написанных на C#, точно так же, как это делается для программ на VB.NET, J# и др.

Название языка

Нота Шаблон:Iw

Название «Си шарп» (от англ. sharp — диез) происходит от буквенной музыкальной нотации, где латинской букве C соответствует нота До, а знак диез (англ. sharp) означает повышение соответствующего ноте звука на полутон<ref>Шаблон:Cite web</ref>, что аналогично названию языка C++, где «++» обозначает инкремент переменной. Название также является игрой с цепочкой CC++ → C++++(C#), так как символ «#» можно представить состоящим из 4 знаков «+»<ref>Шаблон:Cite web</ref>.

Из-за технических ограничений на отображение (стандартные шрифты, браузеры и т. д.), а также из-за того, что знак диеза ♯ не представлен на стандартной клавиатуре компьютера, при записи имени языка программирования используют знак решётки (#)<ref name="MS CSharp FAQ">Шаблон:Cite web</ref>. Это соглашение отражено в Спецификации языка C# ECMA-334<ref name="ECMA-334">Шаблон:Книга Шаблон:Cite web</ref>. Тем не менее, на практике (например, при размещении рекламы и коробочном дизайне<ref>Шаблон:Cite web</ref>), «Майкрософт» использует знак диеза.

Названия языков программирования не принято переводить, поэтому язык называют, используя транскрипцию, — «Си шарп».

Стандартизация

C# стандартизирован в ECMA (ECMA-334)<ref>Шаблон:Cite web</ref> и ISO (ISO/IEC 23270)<ref>Шаблон:Cite web</ref>.

Известно как минимум о трёх независимых реализациях C#, базирующихся на этой спецификации и находящихся в настоящее время на различных стадиях разработки:

Версии

На протяжении разработки языка C# было выпущено несколько его версий:

Версия Спецификация языка Дата выхода Совместимые версии .NET Совместимая версия Visual Studio
ECMA ISO/IEC Microsoft
C# 1.0 Декабрь 2002 Апрель 2003Шаблон:Недоступная ссылка Январь 2002 Январь 2002 .NET Framework 1.0 Visual Studio .NET (2002)
C# 1.1
C# 1.2
Октябрь 2003 Апрель 2003 .NET Framework 1.1 Visual Studio .NET 2003
C# 2.0 Июнь 2006 Сентябрь 2006 Сентябрь 2005<ref name="note">Спецификация по Microsoft C# 2.0 содержит описание лишь новых возможностей версии 2.0. Особенности версии описаны в спецификации 1.2, приведенной выше.</ref> Ноябрь 2005 .NET Framework 2.0
.NET Framework 3.0
Visual Studio 2005
C# 3.0 colspan="2" rowspan="2" Шаблон:Lang-ref<ref name=autogenerated1>Для версий языка C# 3.0, 4.0 и 5.0 пока нет утверждённых ECMA или ISO/IEC спецификаций.</ref> Август 2007 Ноябрь 2007 .NET Framework 2.0 (кроме LINQ)
.NET Framework 3.0 (кроме LINQ)
.NET Framework 3.5
Visual Studio 2008
C# 4.0 Апрель 2010 Апрель 2010 .NET Framework 4.0 Visual Studio 2010
C# 5.0 Декабрь 2017 Декабрь 2018 Июнь 2013 Август 2012 .NET Framework 4.5 Visual Studio 2012
C# 6.0 Июнь 2022 Шаблон:Lang-ref Июль 2015 .NET Framework 4.6
.NET Core 1.0
.NET Core 1.1
Visual Studio 2015
C# 7.0 Декабрь 2023 Сентябрь 2023 Март 2017 .NET Framework 4.6.2
.NET Framework 4.7
Visual Studio 2017 15.0
C# 7.1 colspan="2" rowspan="8" Шаблон:Lang-ref Август 2017 .NET Core 2.0 Visual Studio 2017 15.3
C# 7.2 Ноябрь 2017 Visual Studio 2017 15.5
C# 7.3 Май 2018 .NET Core 2.1
.NET Core 2.2
.NET Framework 4.8
Visual Studio 2017 15.7
C# 8.0 Сентябрь 2019 .NET Core 3.0
.NET Core 3.1
.NET Framework 4.8
Visual Studio 2019 16.3
C# 9.0 Сентябрь 2020 .NET 5.0 Visual Studio 2019 16.8
C# 10.0 Июль 2021 .NET 6.0 Visual Studio 2022 17.0
C# 11.0 Ноябрь 2022 .NET 7.0 Visual Studio 2022 17.4
C# 12.0 Ноябрь 2023 .NET 8.0 Visual Studio 2022 17.8<ref>Шаблон:Cite web</ref>
Общая информация по версиям
Версия Нововведения
C# 2.0
  • Частичные типы
  • Обобщённые типы (generics)
  • Итераторы и ключевое слово yield
  • Анонимные методы
  • Оператор null-объединения
  • Nullable-типы
C# 3.0
  • Запросы, интегрированные в язык (LINQ)
  • Инициализаторы объектов и коллекций
  • Лямбда-выражения
  • Деревья выражений
  • Неявная типизация и ключевое слово var
  • Анонимные типы
  • Методы расширения
  • Автоматические свойства
C# 4.0
  • Динамическое связывание и ключевое слово dynamic
  • Именованные и опциональные аргументы
  • Обобщенная ковариантность и контрвариантность
  • Библиотека TPL, концепция задач и классы Task, Parallel
  • Класс MemoryCache
  • Классы параллельных коллекций
C# 5.0
  • Шаблон TAP
  • Асинхронные методы async и await
  • Сведения о вызывающем объекте
C# 6.0
  • Компилятор как сервис
  • Импорт членов статических типов в пространство имён
  • Фильтры исключений
  • await в блоках catch/finally
  • Инициализаторы автосвойств
  • Автосвойства только для чтения
  • null-условные операции (?. и ?[])
  • Интерполяция строк
  • Оператор nameof
  • Инициализатор словаря
  • Функции сжатые до выражений
C# 7.0<ref name="seven">Шаблон:Cite web</ref>
  • out-переменные
  • Сопоставление с шаблоном
  • Шаблоны с is
  • Шаблоны и выражение switch
  • Кортежи
  • Распаковка кортежей (деконструкторы)
  • Локальные функции
  • Улучшения литералов
  • Локальные переменные и возвращаемые значения по ссылке
  • Расширение списка типов, возвращаемых асинхронными методами
  • Больше членов класса в виде выражений
  • throw выражения
C# 8.0
  • Члены только для чтения
  • Члены интерфейса по умолчанию
  • Улучшения сопоставления шаблонов
  • Объявления using
  • Статические локальные функции
  • Удаляемые ссылочные структуры
  • Ссылочные типы, допускающие значение NULL
  • Асинхронные потоки
  • Индексы и диапазоны
  • Присваивание объединения со значением NULL
  • Неуправляемые сконструированные типы
  • Выражения stackalloc во вложенных выражениях
  • Больше членов класса в виде выражений
  • Улучшения интерполированных строк
C# 9.0
  • Оператор объединения с null (??)
  • Пустые параметры для лямбда-выражений
  • Native Int: nint, nuint
  • Дизъюнктное объединение
  • Добавлено with-выражения
  • новый модификатор initonly
C# 10.0
  • Добавление role="alert" атрибуты сообщений
  • ОбновленияCounter компонент для добавления role="status"
  • Замена ul в NavBar компонент для nav
  • Новое название кнопки переключенияNavBar
  • Переход к использованию более семантической разметки
C# 11.0
  • Необработанные строковые литералы
  • Поддержка универсальной математики
  • Универсальные атрибуты
  • Строковые литералы UTF-8
  • Новые строки в выражениях интерполяции строк
  • Шаблоны списка
  • Локальные типы файлов
  • Обязательные элементы
  • Автоматические структуры по умолчанию
  • Сопоставление Span<char> шаблонов для константы string
  • Расширенные nameof область
  • Числовой intPtr
  • ref поля и scoped ref
  • Улучшенное преобразование групп методов для делегирования.

Версия 1.0

Проект C# был начат в декабре 1998 и получил кодовое название COOL (C-style Object Oriented Language). Версия 1.0 была анонсирована вместе с платформой .NET в июне 2000 года, тогда же появилась и первая общедоступная бета-версия; C# 1.0 окончательно вышел вместе с Microsoft Visual Studio .NET в феврале 2002 года.

Первая версия C# напоминала по своим возможностям Java 1.4, несколько их расширяя: так, в C# имелись свойства (выглядящие в коде как поля объекта, но на деле вызывающие при обращении к ним методы класса), индексаторы (подобные свойствам, но принимающие параметр как индекс массива), события, делегаты, циклы foreach, структуры, передаваемые по значению, автоматическое преобразование встроенных типов в объекты при необходимости (boxing), атрибуты, встроенные средства взаимодействия с неуправляемым кодом (DLL, COM) и прочее.

Кроме того, в C# решено было перенести некоторые возможности C++, отсутствовавшие в Java: беззнаковые типы, перегрузку операторов (с некоторыми ограничениями, в отличие от C++), передача параметров в метод по ссылке, методы с переменным числом параметров, оператор goto (с ограничениями). Также в C# оставили ограниченную возможность работы с указателями — в местах кода, специально обозначенных словом unsafe и при указании специальной опции компилятору.

Версия 2.0

Проект спецификации C# 2.0 впервые был опубликован Microsoft в октябре 2003 года; в 2004 году выходили бета-версии (проект с кодовым названием Whidbey), C# 2.0 окончательно вышел 7 ноября 2005 года вместе с Visual Studio 2005 и .NET 2.0.

Новые возможности в версии 2.0
  • Частичные типы (разделение реализации класса более чем на один файл).
  • Обобщённые, или параметризованные типы (generics). В отличие от шаблонов C++, они поддерживают некоторые дополнительные возможности и работают на уровне виртуальной машины. Вместе с тем, параметрами обобщённого типа не могут быть выражения, они не могут быть полностью или частично специализированы, не поддерживают шаблонных параметров по умолчанию, от шаблонного параметра нельзя наследоваться, и т. д.<ref>Шаблон:Cite web</ref>
  • Новая форма итератора, позволяющая создавать сопрограммы с помощью ключевого слова yield, подобно Python и Ruby.
  • Анонимные методы, обеспечивающие функциональность замыкания.
  • Оператор null-объединения: '??': return obj1 ?? obj2; означает (в нотации C# 1.0) return obj1!=null ? obj1 : obj2;.
  • Обнуляемые (nullable) типы — значения (обозначаемые вопросительным знаком, например, int? i = null;), представляющие собой те же самые типы-значения, способные принимать также значение null. Такие типы позволяют улучшить взаимодействие с базами данных через язык SQL.
  • Возможность создавать хранимые процедуры, триггеры и даже типы данных на .Net языках (в том числе и на C#).
  • Поддержка 64-разрядных вычислений, что кроме всего прочего, позволяет увеличить адресное пространство и использовать 64-разрядные примитивные типы данных.

Версия 3.0

В июне 2004 года Андерс Хейлсберг впервые рассказал на сайте Microsoft о планируемых расширениях языка в C#3.0<ref>Шаблон:Cite web</ref>. В сентябре 2005 года вышли проект спецификации C# 3.0 и бета-версия C# 3.0, устанавливаемая в виде дополнения к существующим Visual Studio 2005 и .NET 2.0. Окончательно эта версия языка вошла в Visual Studio 2008 и .NET 3.5.

Новые возможности в версии 3.0

В C# 3.0 появились следующие радикальные добавления к языку:

  • ключевые слова select, from, where, позволяющие делать запросы из XML документов, коллекций Шаблон:Nobr Эти запросы имеют сходство с запросами SQL и реализуются компонентом LINQ. (Сама фраза «language integrated query» переводится «запрос, интегрированный в язык».)
  • Инициализация объекта вместе с его свойствами:
<source lang="csharp" line="1">Customer c = new Customer(); c.Name = "James"; c.Age=30;</source>
можно записать как
<source lang="csharp" line="1">Customer c = new Customer { Name = "James", Age = 30 };</source>
<source lang="csharp" line="1">listOfFoo.Where(delegate(Foo x) { return x.size > 10; });</source>
теперь можно записать как
<source lang="csharp" line="1">listOfFoo.Where(x => x.size > 10);</source>
  • Деревья выражений:
лямбда-выражения теперь могут представляться в виде структуры данных, доступной для обхода во время выполнения, тем самым позволяя транслировать строго типизированные C#-выражения в другие домены (например, выражения SQL).
  • Неявная типизация: Вывод типов локальной переменной. Для неявной типизации вместо названия типа данных используется ключевое слово var. Затем уже при компиляции компилятор сам выводит тип данных исходя из присвоенного значения:var x = "hello"; вместо string x = "hello";
  • Анонимные типы: var x = new { Name = "James" };
  • Методы расширения. Появилась возможность добавления новых методов в уже существующие классы. Реализуется с помощью ключевого слова this при первом параметре статической функции статического класса.

<source lang="csharp" line="1"> public static class StringExtensions {

 public static int ToInt32(this string val)
 {
   return Int32.Parse(val);
 }

} // ... string s = "10"; int x = s.ToInt32(); </source>

  • Автоматические свойства: компилятор сгенерирует закрытое (private) поле и соответствующие аксессор и мутатор для кода вида

<source lang="csharp" line="1"> public string Name { get; private set; } </source> C# 3.0 совместим с C# 2.0 по генерируемому MSIL-коду; улучшения в языке — чисто синтаксические и реализуются на этапе компиляции. Например, многие из интегрированных запросов LINQ можно осуществить, используя безымянные делегаты в сочетании с предикатными методами над контейнерами наподобие List.FindAll и List.RemoveAll.

Версия 4.0

Превью C# 4.0 было представлено в конце 2008 года, вместе с CTP-версией Visual Studio 2010.

Visual Basic 10.0 и C# 4.0 были выпущены в апреле 2010 года, одновременно с выпуском Visual Studio 2010.

Новые возможности в версии 4.0<ref>Шаблон:Cite web</ref>
  • Возможность использования позднего связывания, для использования:
    • с языками с динамической типизацией (Python, Ruby)
    • с COM-объектами
    • отражения (reflection)
    • объектов с изменяемой структурой (DOM). Появляется ключевое слово dynamic.
  • Именованные и опциональные параметры
  • Новые возможности COM interop
  • Ковариантность и контравариантность обобщенных интерфейсов и делегатов
  • Контракты в коде (Code Contracts)
  • Библиотека параллельных задач TPL (Task Parallel Library), концепция задач и классы Task, TaskFactory, Parallel
  • Добавлен класс MemoryCache, который предназначен для кэширования контента. Он похож на класс Cache ASP.NET, но его можно использовать при написании веб- / графических / консольных приложений.
  • Добавлено пространство имен System.Collections.Concurrent и новые классы параллельных коллекций (ConcurrentQueue, ConcurrentStack, ConcurrentBag,…), которые предоставляют не только большую эффективность, но и более полную потокобезопасность.

Примеры: <source lang="csharp" line="1"> dynamic calc = GetCalculator(); int sum = calc.Add(10, 20); // Динамический вызов </source> <source lang="csharp" line="1"> public void SomeMethod(int x, int y = 5, int z = 7); // Опциональные параметры </source>

Версия 5.0

Новые возможности в версии 5.0

  • Шаблон TAP (Task-based Asynchronous Pattern). TAP использует один метод для представления инициализации и завершения асинхронной операции.
  • Асинхронные методы (async и await) — как реализация шаблона TAP.
  • Сведения о вызывающем объекте

Версия 6.0

Новые возможности в версии 6.0

  • null-условные операторы. Добавлены новые операторы: ?. и ?[]:

<source lang="csharp" line="1"> int? length = customers?.Length; // null if customers is null Customer first = customers?[0]; // null if customers is null </source>

  • Функции сжатые до выражений (expression-bodied functions). Теперь определение метода может быть задано с использованием лямбда-синтаксиса:

<source lang="csharp" line="1"> public Point Move(int dx, int dy) => new Point(x + dx, y + dy); </source>

  • Инициализаторы автосвойств. Автосвойства теперь можно инициализировать при объявлении:

<source lang="csharp" line="1"> public string First { get; set; } = "Jane"; </source>

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

<source lang="csharp" line="1"> public string First { get; } = "Jane"; </source>

  • Инициализаторы индексов. Теперь можно инициализировать не только объекты и коллекции, но и словари:

<source lang="csharp" line="1">var numbers = new Dictionary<int, string> {

   [7] = "seven",
   [9] = "nine",
   [13] = "thirteen"

};</source>

  • Интерполяция строк. Вместо использования конструкций с String.Format(), например:

<source lang="csharp" line="1"> var s = String.Format("{0} is {1} yearШаблон:S old", p.Name, p.Age); </source> теперь можно размещать код прямо в строке: <source lang="csharp" line="1"> var s = $"{p.Name} is {p.Age} yearШаблон:S old"; </source>

  • Фильтры исключений. Появилась возможность задавать условия для блоков catch:

<source lang="csharp" line="1"> try { … } catch (Exception e) when (Log(e)) { … } </source>

  • Импорт статических функций типов. Теперь доступ к статическим членам типов возможен без указания полного имени этих членов:

<source lang="csharp" line="1"> using static System.Console; using static System.Math; class Program {

   static void Main()
   {
       WriteLine(Sqrt(3*3 + 4*4)); 
   }

} </source>

  • Оператор nameof. Новый оператор, который возвращает компактное строковое представление для переданного в качестве аргумента типа:

<source lang="csharp" line="1"> WriteLine(nameof(person.Address.ZipCode)); // prints "ZipCode" </source>

  • Для асинхронного программирования была добавлена возможность использования операторов await внутри блоков catch и finally:

<source lang="csharp" line="1"> Resource res = null; try {

   res = await Resource.OpenAsync(…);       // You could do this.

} catch(ResourceException e) {

   await Resource.LogAsync(res, e);         // Now you can do this …

} finally {

   if (res != null) await res.CloseAsync(); // … and this.

} </source>

Версия 7.0

Новые возможности в версии 7.0<ref name="seven" />

  • out-переменные, которые позволяют объявить переменные сразу в вызове метода (причем областью видимости для таких переменных является внешний блок):

<source lang="csharp" line="1">p.GetCoordinates(out int x, out int y);</source>

  • Сопоставление с шаблоном. Вводится понятие шаблона (pattern), который представляет собой синтаксическую конструкцию, позволяющую проверить соответствие переменной определённой форме и извлечь из неё информацию.
  • Шаблоны с is (is теперь может использоваться не только с типом, но и с шаблоном — в качестве правого аргумента)
  • Шаблоны и выражение switch. Варианты использования switch были расширены, теперь можно:
    • использовать любые типы (не только примитивные);
    • использовать шаблоны в выражениях case;
    • добавлять дополнительные условия к выражениям case (используя ключевое слово when).
  • Кортежи. Добавлен тип кортеж значений (структура ValueTuple) и синтаксис работы с данными этого типа:

<source lang="csharp" line="1">(string, string, string) LookupName(long id) // возвращаемый тип - кортеж {

   ... // инициализируем данные
   return (first, middle, last); // литерал кортежа

}</source>

  • Распаковка кортежей. Была добавлена новая синтаксическая конструкция деконструктор, позволяющая извлечь кортеж, состоящий из членов класса.
  • Локальные функции. Теперь функцию, которая используется только в теле какого-либо метода, можно объявить прямо в теле этого метода.
  • Улучшения литералов. Были добавлены бинарные литералы и символ разделителя (_) в числовых литералах.
  • Локальные переменные и возвращаемые значения по ссылке. Расширена функциональность ключевого слова ref. Теперь можно возвратить данные из метода или сохранить их в локальной переменной по ссылке.
  • Расширение списка типов, возвращаемых асинхронными методами
  • Больше членов класса в виде выражений. Синтаксис функций, сжатых до выражений (expression-bodied functions), теперь применим для сеттеров, геттеров, конструкторов и деструкторов.
  • throw-выражения. Теперь можно использовать throw в функциях, сжатых до выражений (expression-bodied functions):

<source lang="csharp" line="1">public string GetLastName() => throw new NotImplementedException();</source>

Версия 8.0

Новые возможности в версии 8.0<ref>Шаблон:Cite web</ref>

  • Модификатор readonly. Был создан для обозначения члена, который не изменит состояние.
  • Методы интерфейсов по умолчанию. Теперь при создании метода интерфейса можно объявить его реализацию по умолчанию, которую можно переопределить в классе, который реализует этот интерфейс.
  • Сопоставление шаблонов. Возможность позволяет работать с шаблонами в зависимости от формата в связанных, но различных типах данных.
    • Рекурсивные шаблоны. Является выражением шаблона, которое применяется к результатам другого выражения шаблона.
    • Выражения switch позволяют сократить количество case и break, а также фигурных скобок.<syntaxhighlight lang="csharp" line="1">

public enum Rainbow {

   Red,
   Orange,
   Yellow,
   Green,
   Blue,
   Indigo,
   Violet

}

public static RGBColor FromRainbow(Rainbow colorBand) =>

   colorBand switch
   {
       Rainbow.Red    => new RGBColor(0xFF, 0x00, 0x00),
       Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
       Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
       Rainbow.Green  => new RGBColor(0x00, 0xFF, 0x00),
       Rainbow.Blue   => new RGBColor(0x00, 0x00, 0xFF),
       Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),
       Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
       _              => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)),
   };

</syntaxhighlight>

    • Шаблоны свойств. Позволяет сопоставлять свойства исследуемого объекта с помощью { variable : value } => ... .
    • Шаблоны кортежей. Используется, если нужно работать с несколькими наборами входных данных. (value1, value2,..) => ...
  • Объявление using. Это объявление переменной, которому предшествует ключевое слово using. Оно сообщает компилятору, что объявляемая переменная должна быть удалена в конце области видимости.
  • Статический локальный метод. Теперь можно убедиться в том, что метод не охватывает какие-либо переменные из области видимости с помощью добавления к нему модификатора static.
  • Удаляемые ссылочные структуры. Ссылочные структуры не могут реализовать IDisposable (как и любые другие интерфейсы). Поэтому чтобы удалить ref struct, необходим доступный void Dispose().
  • Типы значений, допускающие значение null. Теперь, чтобы указать, что переменная типа значений допускает значение null, необходимо поставить к имени типа ?
  • Асинхронные потоки. Это во-первых интерфейс IAsyncEnumerable<T>. А во-вторых конструкция foreach с await.<syntaxhighlight lang="csharp" line="1">

public static async System.Collections.Generic.IAsyncEnumerable<int> GenerateSequence() {

   for (int i = 0; i < 20; i++)
   {
       await Task.Delay(100);
       yield return i;
   }

} // or await foreach (var number in GenerateSequence()) {

   Console.WriteLine(number);

} </syntaxhighlight>

  • Асинхронные высвобождаемые типы. Начиная с C# 8.0 язык поддерживает асинхронные освобождаемые типы, реализующие интерфейс System.IAsyncDisposable. Операнд выражения using может реализовывать IDisposable или IAsyncDisposable. В случае IAsyncDisposable компилятор создает код для await, возвращенного Task из IAsyncDisposable.DisposeAsync.
  • Индексы и диапазоны. Диапазоны и индексы обеспечивают лаконичный синтаксис для доступа к отдельным элементам или диапазонам в последовательности. Нововведение включает в себя операторы ^ и .. , а также System.Index и System.Range
  • Оператор присваивания объединения с null. Оператор ??= можно использовать для присваивания значения правого операнда левому операнду только в том случае, если левый операнд имеет значение null.<syntaxhighlight lang="csharp" line="1">

List<int> numbers = null; int? i = null;

numbers ??= new List<int>(); numbers.Add(i ??= 17); numbers.Add(i ??= 20);

Console.WriteLine(string.Join(" ", numbers)); // output: 17 17 Console.WriteLine(i); // output: 17 </syntaxhighlight>

  • Неуправляемые сконструированные типы. Начиная с C# 8.0, сконструированный тип значения является неуправляемым, если он содержит поля исключительно неуправляемых типов (например универсальный тип <T>).
  • Выражение stackalloc во вложенных выражениях. Теперь если результат выражения stackalloc имеет тип System.Span<T> или System.ReadOnlySpan<T>, то его можно использовать в других выражениях.<syntaxhighlight lang="csharp" line="1">

Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 }; var ind = numbers.IndexOfAny(stackalloc[] { 2, 4, 6, 8 }); Console.WriteLine(ind); // output: 1 </syntaxhighlight>

  • Порядок маркеров $ и @ в интерполированных строках verbatim теперь может быть любым.

Версия 9.0

Новые возможности в версии 9.0<ref>Шаблон:Cite web</ref>

  • Типы записей. Появилась возможность при помощи ключевого слова record для определения ссылочного типа, предоставляющего функционал инкапсуляции данных. <syntaxhighlight lang="csharp" line="1">public record Person(string FirstName, string LastName);</syntaxhighlight> По умолчанию типы записей является неизменяемыми. В отличие от других ссылочных типов, переменные типов записей считаются равными, если равны типы и значения их свойств и полей.
    • Обратимые изменения. Для заданного экземпляра записи при помощи ключевого слова with возможно создание копии с изменёнными значениями указанных свойств и полей.
    • Запись может быть унаследована от записи. Однако запись не может быть унаследована от класса, и наоборот, класс не может быть унаследован от записи.
  • Инициализаторы. C# 9.0 предоставляет синтаксис — ключевое слово init — для задания значений свойств класса при инициализации. <syntaxhighlight lang="csharp" line="1">

public class Person {

   public string FirstName { get; init; }
   public string LastName { get; init; }

}; </syntaxhighlight>

  • Операторы верхнего уровня. Один файл в приложении допускается начать сразу с исполняемых строк кода, минуя ряд таких формальностей, как объявление пространств имён, классов, методов. Такие операторы эквивалентны операторам метода Main.
  • Улучшения сопоставлений шаблонов.
    • Шаблоны типов — соответствуют объекту заданного типа.
    • Логические шаблоны — входные данные должны соответствовать заданной логической операции (and, or, not).
    • Реляционные шаблоны — входные данные должны соответствовать заданной операции сравнения (больше, меньше, равно, больше или равно, меньше или равно) с константой.
  • Улучшения производительности.
  • Допускается опустить тип создаваемого объекта в выражении new, если он известен заранее <syntaxhighlight lang="csharp" line="1">

private List<Person> persons = new(); </syntaxhighlight>

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

Версия 10.0

Новые возможности в версии 10.0<ref>Шаблон:Cite web</ref>

  • Глобальные импорты. С помощью ключевого слова global появилась возможность определить пространства имён, которые будут импортированы глобально во всех файлах проекта. <syntaxhighlight lang="csharp" line="1">

global using System; global using System.Collections.Generic; </syntaxhighlight>

  • Файловая область видимости пространства имён. Объявление пространства имён может быть применено ко всему файлу, что уменьшает уровень отступов в коде. <syntaxhighlight lang="csharp" line="1">

namespace MyNamespace; </syntaxhighlight>

  • Усовершенствованные структуры. Добавлены улучшения в работу со структурами, в том числе возможность инициализации полей непосредственно в теле структуры и поддержка параметров по умолчанию. <syntaxhighlight lang="csharp" line="1">

public struct Point {

   public int X { get; set; } = 0;
   public int Y { get; set; } = 0;

} </syntaxhighlight>

  • Запечатанные интерфейсы. Интерфейсы могут быть объявлены как sealed, что предотвращает их реализацию другими интерфейсами. <syntaxhighlight lang="csharp" line="1">public sealed interface IMyInterface { }</syntaxhighlight>
  • Усовершенствованные операторы и литералы. Поддержка with-оператора для структурных типов, улучшенные string-интерполяции и другие синтаксические улучшения.
  • Улучшенное сопоставление шаблонов. Добавлены новые возможности для сопоставления шаблонов, включая шаблоны списков и возможность использования шаблонов в операторах switch и if. <syntaxhighlight lang="csharp" line="1">

int[] numbers = { 1, 2, 3, 4, 5 }; bool isThreeElementArray = numbers is [_, _, _]; </syntaxhighlight>

  • Поддержка записи структуры и членов записи. Улучшена производительность при использовании структурных типов с поддержкой записи. <syntaxhighlight lang="csharp" line="1">public record struct Point(int X, int Y);</syntaxhighlight>
  • Усовершенствованные атрибуты. Возможность применения атрибутов к более широкому кругу элементов, таких как локальные функции и выражения. <syntaxhighlight lang="csharp" line="1">

[MyCustom] void LocalFunction() { } </syntaxhighlight>

  • Лямбда-выражения. Поддержка более мощных и гибких лямбда-выражений, включая использование типов возврата и деструктуризацию. <syntaxhighlight lang="csharp" line="1">var increment = (int x) => x + 1;</syntaxhighlight>
  • Усовершенствованные async/await. Улучшена работа с асинхронными методами, включая более эффективное управление памятью и потоками.

Версия 11.0

Новые возможности в версии 11.0<ref>Шаблон:Cite web</ref>

  • Статические виртуальные элементы в интерфейсах. Интерфейсы теперь могут включать статические виртуальные и абстрактные члены, что позволяет перегружать операторы и определять статические свойства и методы. Это упрощает реализацию универсальных математических операций. <syntaxhighlight lang="csharp" line="1">

public interface IMyInterface<TSelf, TOther, TResult>

   where TSelf : IMyInterface<TSelf, TOther, TResult> 

{

   static abstract TResult operator +(TSelf left, TOther right); 

} </syntaxhighlight>

  • Проверяемые и непроверяемые операторы. Разработчики могут определять checked и unchecked арифметические операторы, что позволяет компилятору вызывать правильный вариант на основе контекста. <syntaxhighlight lang="csharp" line="1">

public static checked int operator +(MyType left, MyType right) {

   left.Value + right.Value; 

} </syntaxhighlight>

  • Оператор unsigned right-shift. Введен новый оператор >>>, который выполняет сдвиг вправо без знака, упрощая работу с целочисленными типами. <syntaxhighlight lang="csharp" line="1">

int result = -8 >>> 2; </syntaxhighlight>

  • Ослабленные требования к операторам смены. Второй операнд оператора сдвига больше не обязан быть типа int, что делает использование универсальных математических интерфейсов более гибким. <syntaxhighlight lang="csharp" line="1">

MyType value = new MyType(); value >>= 3; </syntaxhighlight>

  • Поддержка универсальной математики. Новые интерфейсы, такие как System.IAdditionOperators<TSelf, TOther, TResult>, позволяют типам реализовывать математические операции более последовательно и удобно. <syntaxhighlight lang="csharp" line="1">

public struct MyNumber : IAdditionOperators<MyNumber, MyNumber, MyNumber> {

   public static MyNumber operator +(MyNumber left, MyNumber right)
   {
       new MyNumber(left.Value + right.Value);
   }

} </syntaxhighlight>

  • Расширенные возможности инициализации типов. Теперь можно задавать значения полей прямо в теле структуры и использовать параметры по умолчанию. <syntaxhighlight lang="csharp" line="1">

public struct Point {

   public int X { get; set; } = 0; 
   public int Y { get; set; } = 0; 

} </syntaxhighlight>

Версия 12.0

Новые возможности в версии 12.0<ref>Шаблон:Cite web</ref>

  • Статические абстрактные и виртуальные методы в интерфейсах. Интерфейсы теперь могут содержать статические абстрактные и виртуальные методы, что позволяет определять поведение для универсальных математических операций. <syntaxhighlight lang="csharp" line="1">

public interface IMyInterface<TSelf, TOther, TResult>

   where TSelf : IMyInterface<TSelf, TOther, TResult> 

{

   static abstract TResult operator +(TSelf left, TOther right); 
   static virtual TResult Add(TSelf left, TOther right) 
   {
       return left + right;
   }

} </syntaxhighlight>

  • Поддержка коллекций с неизменяемыми элементами. Введена новая коллекция ImmutableArray, которая обеспечивает неизменяемость элементов и повышение производительности. <syntaxhighlight lang="csharp" line="1">

var immutableArray = ImmutableArray.Create(1, 2, 3, 4); </syntaxhighlight>

  • Улучшенные структуры данных. В C# 12 введены новые типы данных, такие как readonly struct и ref readonly struct, для оптимизации работы с памятью. <syntaxhighlight lang="csharp" line="1">

public readonly struct Point {

   public int X { get; } 
   public int Y { get; }
   public Point(int x, int y) 
   {
       X = x;
       Y = y;
   }

} </syntaxhighlight>

  • Расширенные возможности для типов записи. Теперь записи поддерживают наследование и могут содержать методы с телами. <syntaxhighlight lang="csharp" line="1">

public record Person(string Name) {

   public virtual string GetName() => Name;

}

public record Employee(string Name, int EmployeeId) : Person(Name) {

   public override string GetName() => $"{Name} (ID: {EmployeeId})";

} </syntaxhighlight>

  • Поддержка типов с произвольным количеством параметров. Введены новые методы для работы с переменным числом параметров, упрощая использование таких типов в коде. <syntaxhighlight lang="csharp" line="1">

public void PrintValues(params int[] values) {

   foreach (var value in values) 
   {
       Console.WriteLine(value);
   }

}

PrintValues(1, 2, 3, 4); </syntaxhighlight>

  • Расширенные возможности компилятора. В C# 12 компилятор получил новые возможности для оптимизации и проверки кода, включая улучшенную поддержку анализаторов и генераторов исходного кода.

Пример «Hello, World!»

Ниже представлен код классической программы «Hello world» на C# для консольного приложения:

<source lang="csharp" line="1">Console.WriteLine("Hello World!");</source>

и код этой же программы для приложения Windows Forms:

<source lang="csharp" line="1"> namespace WindowsForms;

public class Program {

   [STAThread]
   public static void Main() => new DemoForm().ShowDialog();

}

public class DemoForm : Form {

   Label label = new Label();
   public DemoForm()
   {
       label.Text = "Hello World!";
       this.Controls.Add(label);
       this.StartPosition = FormStartPosition.CenterScreen;
       this.BackColor = Color.White;
       this.FormBorderStyle = FormBorderStyle.Fixed3D;
   }

} </source>

Реализации

Существует несколько реализаций C#:

Примечания

Шаблон:Примечания

Литература

Ссылки

Шаблон:Навигация

Шаблон:ВС Шаблон:C Sharp Шаблон:DotNET Шаблон:Ecma International Standards Шаблон:Стандарты ISO Шаблон:Язык программирования Си Шаблон:Microsoft Research Шаблон:Свободное и открытое программное обеспечение Microsoft