C# (произносится Си-шарп) — объектно-ориентированный язык программирования с безопасной системой типизации для платформы .NET. Разработана Андерсом Гейлсбергом, и Питером Гольде под эгидой Microsoft Research (принадлежит Microsoft).
Синтаксис C# близок к С++ и Java. Язык имеет строгую статическую типизацию, поддерживает полиморфизм, перегрузку операторов, указатели на функции-члены классов, атрибуты, события, свойства, исключения, комментарии в формате XML. Переняв многое от своих предшественников — языков С++, Object Pascal, Модула и Smalltalk — С# опираясь на практику их использования, исключает некоторые модели, зарекомендовавшие себя как проблематичные при разработке программных систем, например, язык С# в отличие от C++, не предполагает множественное наследование классов.
История возникновения
C# является очень близким родственником языка программирования Java. Язык Java была создана компанией Sun Microsystems, когда глобальное развитие интернета поставил задачи распределенных вычислений. Взяв за основу популярную язык C++, Java исключила из него потенциально опасные вещи (вроде указателей без контроля выхода за пределы). Для распределенных вычислений была создана концепция виртуальной машины и машинно-независимый байт-кода, своего рода посредника между исходным текстом программ и аппаратными инструкциями компьютера или другого интеллектуального устройства.
Java приобрела немалую популярность, и была лицензирована также и компанией Microsoft. Но, со временем, Sun начала обвинять Microsoft, что и при создании своего клона Java делает ее совместимой исключительно с платформой Windows, чем противоречит самой концепции машинно-независимого среды выполнения и нарушает лицензионное соглашение. Microsoft отказалась пойти навстречу требованиям Sun, и поэтому выяснение отношений приобрело статус судебного процесса. Суд признал позицию Sun справедливой, и обязал Microsoft отказаться от использования Java.
В этой ситуации в Microsoft решили, пользуясь своим господствующим положением на рынке, создать свой собственный аналог Java — язык, для которого корпорация будет полноценным собственником. Эта новообразованная речь получила название C#. Она унаследовала от Java концепции виртуальной машины (среду .NET), байт-кода (WM) и большей безопасности исходного кода программ, плюс учла опыт использования программ на Java.
Нововведением C# стала возможность более легкого взаимодействия, по сравнению с языками-предшественниками, с кодом программ, написанных на других языках, что является важным при создании крупных проектов. Если программы на разных языках выполняются на платформе .NET, .NET берет на себя хлопоты по совместимости программ (то есть типов данных, по конечному счету).
По состоянию на сегодня C# определено флагманской языке корпорации Microsoft, потому что она наиболее полно использует новые возможности .NET. Остальные языков программирования, хоть и поддерживаются, но признаны такими, что имеют наследственные пробелы по использованию .NET. Строка в C# является ссылочным типом.
Название языка
Символ " # " в названии языка можно интерпретировать и как две пары плюсов ++, намекающие на новый шаг в развитии языка по сравнению с C++ (подобно шага от C к C++), и как музыкальный символ диез, вместе с буквой C, что составляет в английском языке название ноты до-диез. Последнее и дало название языку. Несмотря на то, что символ # (октоторп) на самом деле является символом для обозначения номера на большинстве клавиатур и отличается от символа диез ♯ (Unicode U+266F), Microsoft, как автор речи, неоднократно обращалась к своим клиентам с просьбой принять такую стилизацию.
Версии
Версия 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++, они поддерживают некоторые дополнительные возможности и работают на уровне виртуальной машины. Вместе с тем, параметрами обобщенного типа не могут быть выражения.
- Новая форма итератора, что позволяет создавать сопрограммы с помощью ключевого слова yield, подобно Python и Руби.
- Анонимные методы, обеспечивающие функциональность замыкания.
- Оператор ??: return obj1 ?? obj2; значит (в нотации C# 1.0) return obj1!=null ? obj1 : obj2;.
- Типы-значения обнуляются (nullable), (обозначаемые знаком вопроса, например, int? i = null;) являются теми же самыми типами-значениями, которые могут принимать значение null. Такие типы позволяют улучшить взаимодействие с базами данных через язык SQL.
Версия 3.0
В июне 2004 года Андерс Гейлсберг впервые рассказал на сайте Microsoft о планируемых расширения языка в C# 3.0. В сентябре 2005 года было выпущено проект спецификации C# 3.0 и бета-версия C# 3.0, которая устанавливается в виде дополнения к существующим Visual Studio 2005 и .NET 2.0. Официально версия C# 3.0 увидела свет 19 ноября 2007 года в составе .NET Framework 3.5.
В C# 3.0 появились такие радикальные дополнения и изменения:
- Ключевые слова select, from, where, позволяющие делать запросы с SQL, XML, коллекции прочее (запрос, интегрированный в язык — LINQ)
- Инициализация объекта вместе с его свойствами:
Customer с = new Customer(); из.Name = "James";
будет иметь вид:
Customer с = new Customer { Name = "James" };
- Лямбда-выражения (анонимные функции):
listOfFoo.Where(delegate(Foo x) { return x.size > 10; });
будет иметь вид:
listOfFoo.Where(x => x.size > 10);
- Автоматическое определение типов локальных переменных:
string x = "hello";
будет иметь вид:
var x = "hello";
- Безымянные типы:
var x = new { Name = "James" };
- Методы-расширения — добавление метода в существующий класс с помощью ключевого слова this при первом параметре статической функции.
C# 3.0 совместим с C# 2.0 с генерированным WM-кодом; улучшения в языке — чисто синтаксические и реализуются на этапе компиляции. Например, многие из интегрированных запросов LINQ можно реализовать в текущих версиях используя безымянные делегаты в сочетании с предикативними методами над контейнерами, вроде List.FindAll и List.RemoveAll.
Версия 4.0
Выпуск четвертой версии языка программирования C# не случайно совпал с выпуском новой версии .NET Framework. Он имел целью создание инфраструктуры для реализации языков динамической типизации. Что существенно улучшило поддержку динамических API в C# было желанным для начала работ над языком TypeScript и было использовано имеющимися реализациями, например PowerShell.
Новые возможности в версии 4.0:
- Covariant
- Динамическая диспетчеризация — ключевое слово dynamic указывает компилятору отложить решения ссылок на метод до периода исполнения.
// Так делали вызов методов COM в C# 4.0 object o = GetObject(); Type t = o.GetType(); object result = t.InvokeMember("MyMethod", BindingFlags.InvokeMethod, null, o, new object[] { }); int i = Convert.ToInt32(result); // C# 4.0 dynamic o = GetObject(); int i = o.MyMethod();
- DLR[en] — библиотека промежуточного уровня, что унифицирует взаимодействие динамических API и CLR
- Именованные аргументы и параметры с устоявшимися значениями — делают код более лаконичным. Язык C не поддерживает перегрузку методов, поэтому большинство унифицированных API имеет методы с огромным списком аргументов.
class Logger{ public void Log(int severity=0, string message){}
void Info(string info){ Log(message:info); } }
- Свойства индексаторы
- Возможность пропуска ref в вызовах COM
Document d = new Document(); // Так делали вызов методов COM в C# 4.0 object filename = "Foo.docx"; d.SaveAs(ref filename, // ... // C# 4.0 создаст промежуточную переменную вместо литерала "Foo.docx" // и подставит с модификатором ref d.SaveAs(FileName: "Foo.docx");
- Встраивание типов "COM Должна" — лишило разработчиков хлопот с поставкой PIA
Версия 5.0
- Асинхронные методы
- Сведения об объекте, что делает вызов
----------------------------------------------------------------------------------------------
После 5 версии и до 8 изменения были незначительны, но глобальны, поэтому я их пропущу.
----------------------------------------------------------------------------------------------
Версия 8.0
C# 8.0 доступен на .NET Core 3.x и .NET Standard 2.1.
public readonly override string ToString() => $"({X}, {Y}) это {Distance} от начала";
Версия 9.0
C# 9.0 доступен только на .NET 5.
Записи типа
Ссылочные типы имеют семантику определенных типов для проверки равенства. Это достигается с помощью реализации методов сравнения и вычисления хеша аналогично определенных типов. Записи типа по определению неизменны.
Пример записового типа, представляющий точку на декартовой системе координат:
public record Point { public int X { get; } public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y); }
Пример, демонстрирующий результат сравнения двух объектов-точек:
var point1 = new Point(1, 1); var point2 = new Point(1, 1);
Console.WriteLine(point1 == point2); // результат - true Console.WriteLine(object.ReferenceEquals(point1, point2)); // результат false, поскольку объекты ссылаются на разные области памяти
Также для удобства объявления следующих типов в C# 9 был добавлен новый синтаксис, похожий объявление конструктора, который называется позиционной записью (англ. positional record). С его использованием, ранее приведенный пример записового типа приобретает вид:
public record Point(int X, int Y);
Используя этот синтаксис можно применить параллельное присвоение, присуще для кортежей.
var origin = new Point(0, 0); var (originX, originY) = origin;
Поскольку записи неизменные типы, чтобы создать новый объект из существующего нужно скопировать значения его свойств. Для удобства написания такого кода был добавлен новый выражение with, что создает копию объекта и позволяет изменить свойства результата в форме, подобной выражения инициализации объектов.
var point = new Point(1, 1); // значение свойства объекта: X = 1, Y = 1 point = point with { Y = 0 }; // значения свойств объекта: X = 1, Y = 0
Препроцессор
C# имеет «препроцесорні директивы» (хотя на самом деле он не имеет препроцессора) на основе препроцессора C, это дает программисту возможность определить символы, но не макросы. Условные директивы, такие как #if, #endif, или #else также возможны. Директивы типа #region дают намек редактору для сворачивание фрагментов кода.
Стандартизация
C# стандартизирован в ECMA и ISO
В августе 2000 Microsoft Corporation, Hewlett-Packard и Intel Corporation выступили спонсорами стандартизации спецификации языка C# а также Common Language Infrastructure (CLI) организации по стандартизации ECMA International. В декабре 2001 ECMA выпустила ECMA-334 Спецификация языка C#. C# стала стандартом ISO в 2003 (ISO/IEC 23270:2006 " Information technology—Programming languages—C#. К тому ECMA еще успела адоптировать эквивалентную спецификацию как вторую редакцию C# в декабре 2002.
В июне 2005 ECMA приняла редакцию 3 спецификации C# и отредактировала ECMA-334. Дополнения включали частичные классы, анонимные методы, тип null и дженерики (аналоги шаблонов C++).
В июле 2005 ECMA подала стандарты и соответствующие технические условия ISO/IEC JTC 1 через ускоренной процедуре (Fast-Track). Этот процесс обычно занимает 6-9 месяцев.
Критика
Хотя определение языка C# и CLI стандартизирован ISO и Ecma, что обеспечивает разумный и недискриминационный лицензионный защита (RAND) от патентных исков, Microsoft использует C# и CLI в своей библиотеке Base Class Library (BCL), которая является фундаментом их владельческой платформы .NET framework, которая предоставляет ряд нестандартизированных классов (расширенный I/O, GUI Windows Forms, веб-службы).
В некоторых случаях, где патенты Microsoft относятся к стандартам, использованных в .NET framework, документированы Microsoft, и применены патенты доступны через другие RAND условия или через Обет Открытой Спецификации Microsoft (microsoft's Open Specification Promise, OSP), которые выпускают патентные права публично. Но есть некоторые предостережения и обсуждения о том, что существуют дополнительные аспекты, патентованные Microsoft, что не покрыты, которые могут удерживать независимых реализаторов полного фреймворка.
Microsoft также согласился не подавать иск против разработчиков открытого программного обеспечения о нарушении прав в неприбыльных проєктах для части своего фреймворка, покрытого OSP. Microsoft согласился не нарушать патентных требований относительно продуктов Novell против платных клиентов Novell за исключением перечня продуктов, что явно не вспоминают C# .NET или реализацию .NET от Novell (проект Mono). Однако Novell придерживается точки зрения, что Mono не нарушает ни одного патента Microsoft.. Microsoft также заключил специальное соглашение не судиться против браузерного плагина Moonlight, который опирается на Mono, полученного от Novell.
В замечании, опубликованном на сайте новостей Free Software Foundation в июне 2009 Ричард Столлман предупреждает, что он считает, что Microsoft, возможно, планирует однажды объявить все свободные реализации C# такими, что используют программные патенты» и рекомендовал разработчикам избегать того, что он называет «безвозмездным риском», связанным с «зависимостью свободных реализаций C#. Free Software Foundation позже повторила свои предупреждения, утверждая, что расширение Microsoft Community Promise спецификации ECMA C# и CLI могут не вберігти от вредительства Microsoft открытым реализациям C# поскольку многие специфические для Windows библиотек, включенных в .NET и Mono, не покрытые этими обещаниями. Поэтому большинство ведущих дистрибутивов Линукс, за исключением Novell SUSE Linux, не включают Mono в установку по умолчанию (хотя его и можно скачать из репозиториев).
Реализации
Титульным компилятором C# есть Microsoft Visual C#.
Существуют другие компиляторы C# часто они включают реализации Common Language Infrastructure и библиотеки классов .NET:
- Проект Microsoft Rotor (который теперь называется Shared Source Common Language Infrastructure, лицензированный только для учебного и исследовательского использования) обеспечивает реализацию CLR runtime и компилятор C# и подмножество библиотек фреймворка Common Language Infrastructure, согласно спецификации ECMA (до C# 2.0, и с поддержкой только Windows XP).
- Проект SharpDevelop от компании icsharpcode, который используется как альтернатива Visual Studio. Обеспечивает полную реализацию Common Language Infrastructure. Последняя стабильная версия IDE 4.4 (28 августа 2013), тестовая версия 5.0 (13 февраля 2014). Внешний вид IDE очень напоминает Microsoft Visual C# что делает комфортным переход от одной среды к другой.
- Проект Mono, начатый компанией Xamarin и продлен ее покупателем и преемником Novell, обеспечивает открытый компилятор C# полную открытую реализацию Common Language Infrastructure, включая нужны библиотеки фреймворка согласно спецификации ECMA, и близкую к полной реализации владельческих библиотек классов Microsoft .NET до .NET 2.0, но не специфических библиотек .NET 3.0 и .NET 3.5, как для Mono 2.0.
- Проект DotGNU также предоставляет открытый компилятор Csharp, близкую к полной реализации Common Language Infrastructure, включая нужны библиотеки фреймворка согласно спецификации ECMA, и подмножество некоторых оставленных владельческих библиотек классов Microsoft .NET до .NET 2.0 (не документированы или не включены в спецификации ECMA, но включенные в стандартное определение Microsoft .NET Framework).
- DotNetAnywhere Micro Framework Common Language Runtime нацелен на встроенные системы, и поддерживает почти все спецификации C# 2.0.