Меню
Главная
Случайная статья
Настройки
|
C# (произносится си шарп) — объектно-ориентированный язык программирования общего назначения. Разработан в 1998—2001 годах группой инженеров компании Microsoft под руководством Андерса Хейлсберга и Скотта Вильтаумота[6] как язык разработки приложений для платформы Microsoft .NET Framework и .NET Core. Впоследствии был стандартизирован как 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# и др.
Название языка
Название «Си шарп» (от англ. sharp — диез) происходит от буквенной музыкальной нотации, где латинской букве C соответствует нота До, а знак диез (англ. sharp) означает повышение соответствующего ноте звука на полутон[7], что аналогично названию языка C++, где «++» обозначает инкремент переменной. Название также является игрой с цепочкой C C++ C++++(C#), так как символ «#» можно представить состоящим из 4 знаков «+»[8].
Из-за технических ограничений на отображение (стандартные шрифты, браузеры и т. д.), а также из-за того, что знак диеза не представлен на стандартной клавиатуре компьютера, при записи имени языка программирования используют знак решётки (#)[9]. Это соглашение отражено в Спецификации языка C# ECMA-334[10]. Тем не менее, на практике (например, при размещении рекламы и коробочном дизайне[11]), «Майкрософт» использует знак диеза.
Названия языков программирования не принято переводить, поэтому язык называют, используя транскрипцию, — «Си шарп».
Стандартизация
C# стандартизирован в ECMA (ECMA-334)[12] и ISO (ISO/IEC 23270)[13].
Известно как минимум о трёх независимых реализациях C#, базирующихся на этой спецификации и находящихся в настоящее время на различных стадиях разработки:
Версии
На протяжении разработки языка C# было выпущено несколько его версий:
Общая информация по версиям
Версия |
Нововведения
|
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[17]
|
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++, они поддерживают некоторые дополнительные возможности и работают на уровне виртуальной машины. Вместе с тем, параметрами обобщённого типа не могут быть выражения, они не могут быть полностью или частично специализированы, не поддерживают шаблонных параметров по умолчанию, от шаблонного параметра нельзя наследоваться, и т. д.[18]
- Новая форма итератора, позволяющая создавать сопрограммы с помощью ключевого слова
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[19]. В сентябре 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 документов, коллекций и т. п. Эти запросы имеют сходство с запросами SQL и реализуются компонентом LINQ. (Сама фраза «language integrated query» переводится «запрос, интегрированный в язык».)
- Инициализация объекта вместе с его свойствами:
Customer c = new Customer(); c.Name = "James"; c.Age=30;
- можно записать как
Customer c = new Customer { Name = "James", Age = 30 };
listOfFoo.Where(delegate(Foo x) { return x.size > 10; });
- теперь можно записать как
listOfFoo.Where(x => x.size > 10);
- лямбда-выражения теперь могут представляться в виде структуры данных, доступной для обхода во время выполнения, тем самым позволяя транслировать строго типизированные C#-выражения в другие домены (например, выражения SQL).
- Неявная типизация: Вывод типов локальной переменной. Для неявной типизации вместо названия типа данных используется ключевое слово
var . Затем уже при компиляции компилятор сам выводит тип данных исходя из присвоенного значения:var x = "hello"; вместо string x = "hello";
- Анонимные типы:
var x = new { Name = "James" };
- Методы расширения. Появилась возможность добавления новых методов в уже существующие классы. Реализуется с помощью ключевого слова
this при первом параметре статической функции статического класса.
public static class StringExtensions
{
public static int ToInt32(this string val)
{
return Int32.Parse(val);
}
}
// ...
string s = "10";
int x = s.ToInt32();
- Автоматические свойства: компилятор сгенерирует закрытое (private) поле и соответствующие аксессор и мутатор для кода вида
public string Name { get; private set; }
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[20]
- Возможность использования позднего связывания, для использования:
- с языками с динамической типизацией (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,…), которые предоставляют не только большую эффективность, но и более полную потокобезопасность.
Примеры:
dynamic calc = GetCalculator();
int sum = calc.Add(10, 20); // Динамический вызов
public void SomeMethod(int x, int y = 5, int z = 7); // Опциональные параметры
Версия 5.0
Новые возможности в версии 5.0
- Шаблон TAP (Task-based Asynchronous Pattern). TAP использует один метод для представления инициализации и завершения асинхронной операции.
- Асинхронные методы (
async и await ) — как реализация шаблона TAP.
- Сведения о вызывающем объекте
Версия 6.0
Новые возможности в версии 6.0
- null-условные операторы. Добавлены новые операторы:
?. и ?[] :
int? length = customers?.Length; // null if customers is null
Customer first = customers?[0]; // null if customers is null
- Функции сжатые до выражений (expression-bodied functions). Теперь определение метода может быть задано с использованием лямбда-синтаксиса:
public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
- Инициализаторы автосвойств. Автосвойства теперь можно инициализировать при объявлении:
public string First { get; set; } = "Jane";
- Автосвойства только для чтения. Автосвойства теперь могут быть объявлены без сеттеров:
public string First { get; } = "Jane";
- Инициализаторы индексов. Теперь можно инициализировать не только объекты и коллекции, но и словари:
var numbers = new Dictionary<int, string> {
[7] = "seven",
[9] = "nine",
[13] = "thirteen"
};
- Интерполяция строк. Вместо использования конструкций с
String.Format() , например:
var s = String.Format("{0} is {1} year{{s}} old", p.Name, p.Age);
теперь можно размещать код прямо в строке:
var s = $"{p.Name} is {p.Age} year{{s}} old";
- Фильтры исключений. Появилась возможность задавать условия для блоков
catch :
try { … } catch (Exception e) when (Log(e)) { … }
- Импорт статических функций типов. Теперь доступ к статическим членам типов возможен без указания полного имени этих членов:
using static System.Console;
using static System.Math;
class Program
{
static void Main()
{
WriteLine(Sqrt(3*3 + 4*4));
}
}
- Оператор
nameof . Новый оператор, который возвращает компактное строковое представление для переданного в качестве аргумента типа:
WriteLine(nameof(person.Address.ZipCode)); // prints "ZipCode"
- Для асинхронного программирования была добавлена возможность использования операторов
await внутри блоков catch и finally :
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.
}
Версия 7.0
Новые возможности в версии 7.0[17]
out -переменные, которые позволяют объявить переменные сразу в вызове метода (причем областью видимости для таких переменных является внешний блок):
p.GetCoordinates(out int x, out int y);
- Сопоставление с шаблоном. Вводится понятие шаблона (
pattern ), который представляет собой синтаксическую конструкцию, позволяющую проверить соответствие переменной определённой форме и извлечь из неё информацию.
- Шаблоны с
is (is теперь может использоваться не только с типом, но и с шаблоном — в качестве правого аргумента)
- Шаблоны и выражение
switch . Варианты использования switch были расширены, теперь можно:
- использовать любые типы (не только примитивные);
- использовать шаблоны в выражениях
case ;
- добавлять дополнительные условия к выражениям
case (используя ключевое слово when ).
- Кортежи. Добавлен тип кортеж значений (структура
ValueTuple ) и синтаксис работы с данными этого типа:
(string, string, string) LookupName(long id) // возвращаемый тип - кортеж
{
... // инициализируем данные
return (first, middle, last); // литерал кортежа
}
- Распаковка кортежей. Была добавлена новая синтаксическая конструкция деконструктор, позволяющая извлечь кортеж, состоящий из членов класса.
- Локальные функции. Теперь функцию, которая используется только в теле какого-либо метода, можно объявить прямо в теле этого метода.
- Улучшения литералов. Были добавлены бинарные литералы и символ разделителя (
_ ) в числовых литералах.
- Локальные переменные и возвращаемые значения по ссылке. Расширена функциональность ключевого слова
ref . Теперь можно возвратить данные из метода или сохранить их в локальной переменной по ссылке.
- Расширение списка типов, возвращаемых асинхронными методами
- Больше членов класса в виде выражений. Синтаксис функций, сжатых до выражений (
expression-bodied functions ), теперь применим для сеттеров, геттеров, конструкторов и деструкторов.
throw -выражения. Теперь можно использовать throw в функциях, сжатых до выражений (expression-bodied functions ):
public string GetLastName() => throw new NotImplementedException();
Версия 8.0
Новые возможности в версии 8.0[21]
- Модификатор
readonly . Был создан для обозначения члена, который не изменит состояние.
- Методы интерфейсов по умолчанию. Теперь при создании метода интерфейса можно объявить его реализацию по умолчанию, которую можно переопределить в классе, который реализует этот интерфейс.
- Сопоставление шаблонов. Возможность позволяет работать с шаблонами в зависимости от формата в связанных, но различных типах данных.
- Рекурсивные шаблоны. Является выражением шаблона, которое применяется к результатам другого выражения шаблона.
- Выражения switch позволяют сократить количество case и break, а также фигурных скобок.
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)),
};
- Шаблоны свойств. Позволяет сопоставлять свойства исследуемого объекта с помощью
{ variable : value } => ... .
- Шаблоны кортежей. Используется, если нужно работать с несколькими наборами входных данных.
(value1, value2,..) => ...
- Объявление
using . Это объявление переменной, которому предшествует ключевое слово using . Оно сообщает компилятору, что объявляемая переменная должна быть удалена в конце области видимости.
- Статический локальный метод. Теперь можно убедиться в том, что метод не охватывает какие-либо переменные из области видимости с помощью добавления к нему модификатора
static .
- Удаляемые ссылочные структуры. Ссылочные структуры не могут реализовать
IDisposable (как и любые другие интерфейсы). Поэтому чтобы удалить ref struct , необходим доступный void Dispose() .
- Типы значений, допускающие значение
null . Теперь, чтобы указать, что переменная типа значений допускает значение null , необходимо поставить к имени типа ?
- Асинхронные потоки. Это во-первых интерфейс
IAsyncEnumerable<T> . А во-вторых конструкция foreach с await .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);
}
- Асинхронные высвобождаемые типы. Начиная с C# 8.0 язык поддерживает асинхронные освобождаемые типы, реализующие интерфейс
System.IAsyncDisposable . Операнд выражения using может реализовывать IDisposable или IAsyncDisposable . В случае IAsyncDisposable компилятор создает код для await , возвращенного Task из IAsyncDisposable.DisposeAsync .
- Индексы и диапазоны. Диапазоны и индексы обеспечивают лаконичный синтаксис для доступа к отдельным элементам или диапазонам в последовательности. Нововведение включает в себя операторы
^ и .. , а также System.Index и System.Range
- Оператор присваивания объединения с null. Оператор
??= можно использовать для присваивания значения правого операнда левому операнду только в том случае, если левый операнд имеет значение null .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
- Неуправляемые сконструированные типы. Начиная с C# 8.0, сконструированный тип значения является неуправляемым, если он содержит поля исключительно неуправляемых типов (например универсальный тип <T>).
- Выражение stackalloc во вложенных выражениях. Теперь если результат выражения stackalloc имеет тип
System.Span<T> или System.ReadOnlySpan<T> , то его можно использовать в других выражениях.Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 };
var ind = numbers.IndexOfAny(stackalloc[] { 2, 4, 6, 8 });
Console.WriteLine(ind); // output: 1
- Порядок маркеров
$ и @ в интерполированных строках verbatim теперь может быть любым.
Версия 9.0
Новые возможности в версии 9.0[22]
- Типы записей. Появилась возможность при помощи ключевого слова
record для определения ссылочного типа, предоставляющего функционал инкапсуляции данных. public record Person(string FirstName, string LastName);
По умолчанию типы записей является неизменяемыми. В отличие от других ссылочных типов, переменные типов записей считаются равными, если равны типы и значения их свойств и полей.
- Обратимые изменения. Для заданного экземпляра записи при помощи ключевого слова
with возможно создание копии с изменёнными значениями указанных свойств и полей.
- Запись может быть унаследована от записи. Однако запись не может быть унаследована от класса, и наоборот, класс не может быть унаследован от записи.
- Инициализаторы. C# 9.0 предоставляет синтаксис — ключевое слово
init — для задания значений свойств класса при инициализации. public class Person
{
public string FirstName { get; init; }
public string LastName { get; init; }
};
- Операторы верхнего уровня. Один файл в приложении допускается начать сразу с исполняемых строк кода, минуя ряд таких формальностей, как объявление пространств имён, классов, методов. Такие операторы эквивалентны операторам метода
Main .
- Улучшения сопоставлений шаблонов.
- Шаблоны типов — соответствуют объекту заданного типа.
- Логические шаблоны — входные данные должны соответствовать заданной логической операции (
and , or , not ).
- Реляционные шаблоны — входные данные должны соответствовать заданной операции сравнения (больше, меньше, равно, больше или равно, меньше или равно) с константой.
- Улучшения производительности.
- Допускается опустить тип создаваемого объекта в выражении
new , если он известен заранее private List<Person> persons = new();
- Поддержка статических лямбда-выражений и статических анонимных методов. Как и статические локальные функции, они не могут захватывать нестатические локальные переменные и состояния экземпляра.
- Поддержка применения атрибутов к локальным функциям.
Версия 10.0
Новые возможности в версии 10.0[23]
- Глобальные импорты. С помощью ключевого слова
global появилась возможность определить пространства имён, которые будут импортированы глобально во всех файлах проекта. global using System;
global using System.Collections.Generic;
- Файловая область видимости пространства имён. Объявление пространства имён может быть применено ко всему файлу, что уменьшает уровень отступов в коде.
- Усовершенствованные структуры. Добавлены улучшения в работу со структурами, в том числе возможность инициализации полей непосредственно в теле структуры и поддержка параметров по умолчанию.
public struct Point
{
public int X { get; set; } = 0;
public int Y { get; set; } = 0;
}
- Запечатанные интерфейсы. Интерфейсы могут быть объявлены как
sealed , что предотвращает их реализацию другими интерфейсами. public sealed interface IMyInterface { }
- Усовершенствованные операторы и литералы. Поддержка with-оператора для структурных типов, улучшенные string-интерполяции и другие синтаксические улучшения.
- Улучшенное сопоставление шаблонов. Добавлены новые возможности для сопоставления шаблонов, включая шаблоны списков и возможность использования шаблонов в операторах
switch и if . int[] numbers = { 1, 2, 3, 4, 5 };
bool isThreeElementArray = numbers is [_, _, _];
- Поддержка записи структуры и членов записи. Улучшена производительность при использовании структурных типов с поддержкой записи.
public record struct Point(int X, int Y);
- Усовершенствованные атрибуты. Возможность применения атрибутов к более широкому кругу элементов, таких как локальные функции и выражения.
[MyCustom]
void LocalFunction() { }
- Лямбда-выражения. Поддержка более мощных и гибких лямбда-выражений, включая использование типов возврата и деструктуризацию.
var increment = (int x) => x + 1;
- Усовершенствованные
async/await . Улучшена работа с асинхронными методами, включая более эффективное управление памятью и потоками.
Версия 11.0
Новые возможности в версии 11.0[24]
- Статические виртуальные элементы в интерфейсах. Интерфейсы теперь могут включать статические виртуальные и абстрактные члены, что позволяет перегружать операторы и определять статические свойства и методы. Это упрощает реализацию универсальных математических операций.
public interface IMyInterface<TSelf, TOther, TResult>
where TSelf : IMyInterface<TSelf, TOther, TResult>
{
static abstract TResult operator +(TSelf left, TOther right);
}
- Проверяемые и непроверяемые операторы. Разработчики могут определять
checked и unchecked арифметические операторы, что позволяет компилятору вызывать правильный вариант на основе контекста. public static checked int operator +(MyType left, MyType right)
{
left.Value + right.Value;
}
- Оператор unsigned right-shift. Введен новый оператор
>>> , который выполняет сдвиг вправо без знака, упрощая работу с целочисленными типами.
- Ослабленные требования к операторам смены. Второй операнд оператора сдвига больше не обязан быть типа
int , что делает использование универсальных математических интерфейсов более гибким. MyType value = new MyType();
value >>= 3;
- Поддержка универсальной математики. Новые интерфейсы, такие как
System.IAdditionOperators<TSelf, TOther, TResult> , позволяют типам реализовывать математические операции более последовательно и удобно. public struct MyNumber : IAdditionOperators<MyNumber, MyNumber, MyNumber>
{
public static MyNumber operator +(MyNumber left, MyNumber right)
{
new MyNumber(left.Value + right.Value);
}
}
- Расширенные возможности инициализации типов. Теперь можно задавать значения полей прямо в теле структуры и использовать параметры по умолчанию.
public struct Point
{
public int X { get; set; } = 0;
public int Y { get; set; } = 0;
}
Версия 12.0
Новые возможности в версии 12.0[25]
- Статические абстрактные и виртуальные методы в интерфейсах. Интерфейсы теперь могут содержать статические абстрактные и виртуальные методы, что позволяет определять поведение для универсальных математических операций.
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;
}
}
- Поддержка коллекций с неизменяемыми элементами. Введена новая коллекция
ImmutableArray , которая обеспечивает неизменяемость элементов и повышение производительности. var immutableArray = ImmutableArray.Create(1, 2, 3, 4);
- Улучшенные структуры данных. В C# 12 введены новые типы данных, такие как
readonly struct и ref readonly struct , для оптимизации работы с памятью. public readonly struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y)
{
X = x;
Y = y;
}
}
- Расширенные возможности для типов записи. Теперь записи поддерживают наследование и могут содержать методы с телами.
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})";
}
- Поддержка типов с произвольным количеством параметров. Введены новые методы для работы с переменным числом параметров, упрощая использование таких типов в коде.
public void PrintValues(params int[] values)
{
foreach (var value in values)
{
Console.WriteLine(value);
}
}
PrintValues(1, 2, 3, 4);
- Расширенные возможности компилятора. В C# 12 компилятор получил новые возможности для оптимизации и проверки кода, включая улучшенную поддержку анализаторов и генераторов исходного кода.
Пример «Hello, World!»
Ниже представлен код классической программы «Hello world» на C# для консольного приложения:
Console.WriteLine("Hello World!");
и код этой же программы для приложения Windows Forms:
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;
}
}
Реализации
Существует несколько реализаций C#:
Примечания
- «Поскольку язык С# унаследовал свой синтаксис от C++ и Java…» Трей Нэш. C# 2010: ускоренный курс для профессионалов = Accelerated C# 2010. — М.: Вильямс, 2010. — С. 17. — 592 с. — ISBN 978-5-8459-1638-9.
- «Язык C# <…> унаследовал много полезных возможностей от других языков программирования и напрямую связан с двумя наиболее широко применяемыми в мире компьютерными языками — C и C++, а также с языком Java», однако далее: «Связь между C# и Java более сложная. Оба языка разработаны для создания переносимого кода, базируются на C и C++, используют их синтаксис и объектную модель. Однако между этими языками нет прямой связи, они больше похожи на двоюродных братьев, имеющих общих предков, но отличающихся многими признаками»
-
- Лицензия (Roslyn) в репозитории Github (неопр.). Дата обращения: 4 января 2022. Архивировано 4 января 2022 года.
- Лицензия (.NET CLR) в репозитории Github (неопр.). Дата обращения: 4 января 2022. Архивировано 4 января 2022 года.
-
- Kovacs, James. C#/.NET History Lesson (англ.) (7 сентября 2007). Дата обращения: 23 марта 2011. Архивировано 21 августа 2011 года.
- The A-Z of Programming Languages: C# (англ.). computerworld.com.au (1 октября 2008). Дата обращения: 2 сентября 2014. Архивировано из оригинала 2 апреля 2015 года.
- Microsoft C# FAQ (неопр.). Microsoft. Дата обращения: 25 марта 2008. Архивировано из оригинала 30 апреля 2003 года.
-
- Visual C#.net Standard (неопр.) (JPEG). Microsoft (4 сентября 2003). Дата обращения: 18 июня 2009. Архивировано 21 августа 2011 года.
- Standard ECMA-334 C# Language Specification, 4rd edition (англ.). Ecma International (июнь 2006). Дата обращения: 16 мая 2017. Архивировано 31 октября 2010 года.
- ISO/IEC 23270:2003 Information technology -- C# Language Specification (англ.). International Organization for Standardization (апрель 2003). Дата обращения: 16 мая 2017. Архивировано 5 августа 2017 года.
- Спецификация по Microsoft C# 2.0 содержит описание лишь новых возможностей версии 2.0. Особенности версии описаны в спецификации 1.2, приведенной выше.
- Для версий языка C# 3.0, 4.0 и 5.0 пока нет утверждённых ECMA или ISO/IEC спецификаций.
- Заметки релиза Visual Studio 2022 17.8 (неопр.). Microsoft Learn. Дата обращения: 29 июня 2023. Архивировано 6 августа 2023 года.
- 1 2 Mads Torgersen. New Features in C# 7.0 (англ.). .NET Blog. Microsoft (9 марта 2017). Дата обращения: 7 мая 2017. Архивировано 11 апреля 2017 года.
- Differences Between C++ Templates and C# Generics (C# Programming Guide) (англ.). Microsoft (17 декабря 2016). Дата обращения: 16 мая 2017. Архивировано 7 августа 2021 года.
- Anders Hejlsberg - Programming data in C# 3.0 (англ.). The Channel 9 Team. Microsoft (16 июня 2004). Дата обращения: 16 мая 2017. Архивировано 12 ноября 2018 года.
- Visual Studio 2010: примеры для C# 4.0 (неопр.). Microsoft (17 июля 2012). Дата обращения: 16 мая 2017. Архивировано 28 февраля 2017 года.
- Новые возможности C# 8.0 (рус.). docs.microsoft.com. Дата обращения: 11 июня 2020. Архивировано 8 августа 2020 года.
- Новые возможности C# 9.0 (рус.). docs.microsoft.com. Дата обращения: 29 апреля 2023. Архивировано 8 декабря 2022 года.
- Новые возможности C# 10.0 (рус.). docs.microsoft.com. Дата обращения: 11 апреля 2023. Архивировано 8 декабря 2022 года.
- Новые возможности C# 11.0 (рус.). docs.microsoft.com. Дата обращения: 1 июня 2024. Архивировано 20 декабря 2023 года.
- Новые возможности C# 12.0 (рус.). docs.microsoft.com. Дата обращения: 3 марта 2024. Архивировано 21 декабря 2023 года.
- Dot Net Anywhere (неопр.). Дата обращения: 5 марта 2009. Архивировано 4 мая 2009 года.
Литература
Ссылки
|
|