C Sharp — Вікіпедія

Правильна назва цієї сторінки — C#, але її не можна використовувати через технічні обмеження.
C#
Парадигма об'єктно орієнтована, структурна, імперативна
Дата появи 2001
Творці Microsoft
Розробник Андерс Гейлсберг, Скот Вілтамут та Пітер Гольде
Останній реліз 12 (14 листопада, 2023; 4 місяці тому (2023-11-14))
Система типізації статична, строга, безпечна, керована
Під впливом від Java, Objective-C, C++, Visual Basic, Delphi
Вплинула на Java
Звичайні розширення файлів .cs або .csx
Репозиторій вихідного коду github.com/dotnet/csharplang
github.com/dotnet/roslyn
Вебсайт csharp.net
CMNS: C Sharp у Вікісховищі

C# (вимовляється Сі-шарп) — об'єктно-орієнтована мова програмування з безпечною системою типізації для платформи .NET. Розроблена Андерсом Гейлсбергом, Скотом Вілтамутом та Пітером Гольде під егідою Microsoft Research (належить Microsoft).

Синтаксис C# близький до С++ і Java. Мова має строгу статичну типізацію, підтримує поліморфізм, перевантаження операторів, вказівники на функції-члени класів, атрибути, події, властивості, винятки, коментарі у форматі XML. Перейнявши багато від своїх попередників — мов С++, Object Pascal, Модула і Smalltalk — С#, спираючись на практику їхнього використання, виключає деякі моделі, що зарекомендували себе як проблематичні при розробці програмних систем, наприклад, мова С#, на відміну від C++, не передбачає множинне успадкування класів.

Станом на вересень 2023 року поточна стабільна версія мови C# 11.0, яка була випущена в 2022 році як частина платформи .NET 7.0.[1]

Історія виникнення[ред. | ред. код]

C# є дуже близьким родичем мови програмування Java. Мова Java була створена компанією Sun Microsystems, коли глобальний розвиток інтернету поставив завдання розподілених обчислень. Взявши за основу популярну мову C++, Java виключила з неї потенційно небезпечні речі (на зразок вказівників без контролю виходу за межі). Для розподілених обчислень була створена концепція віртуальної машини та машинно-незалежного байт-коду, свого роду посередника між вихідним текстом програм і апаратними інструкціями комп'ютера чи іншого інтелектуального пристрою.

Java набула чималої популярності, і була ліцензована також і компанією Microsoft. Але, з часом, Sun почала звинувачувати Microsoft, що та при створенні свого клону Java робить її сумісною виключно з платформою Windows, чим суперечить самій концепції машинно-незалежного середовища виконання і порушує ліцензійну угоду. Microsoft відмовилася піти назустріч вимогам Sun, і тому з'ясування стосунків набуло статусу судового процесу. Суд визнав позицію Sun справедливою, і зобов'язав Microsoft відмовитися від позаліцензійного використання Java.

У цій ситуації в Microsoft вирішили, користуючись своїм панівним становищем на ринку, створити свій власний аналог Java — мову, для якої корпорація буде повноцінним власником. Ця новостворена мова отримала назву C#. Вона успадкувала від Java концепції віртуальної машини (середовище .NET), байт-коду (MSIL) і більшої безпечності вихідного коду програм, плюс врахувала досвід використання програм на Java.

Нововведенням C# стала можливість легшої взаємодії, порівняно з мовами-попередниками, з кодом програм, написаних на інших мовах, що є важливим при створенні великих проєктів. Якщо програми на різних мовах виконуються на платформі .NET, .NET бере на себе клопіт щодо сумісності програм (тобто типів даних, за кінцевим рахунком).

Станом на сьогодні[коли?] C# визначено флагманською мовою корпорації Microsoft, бо вона найповніше використовує нові можливості .NET. Решта мов програмування, хоч і підтримуються, але визнані такими, що мають спадкові прогалини щодо використання .NET. Рядок в C# є посилальним типом.[2]

Назва мови[ред. | ред. код]

Символ # у назві мови можна інтерпретувати і як дві пари плюсів ++, що натякають на новий крок у розвитку мови порівняно з 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.[3]. У вересні 2005 року було випущено проєкт специфікації C# 3.0 і бета-версія C# 3.0, що встановлюється у вигляді доповнення до існуючих Visual Studio 2005 і .NET 2.0[4]. Офіційно версія C# 3.0 побачила світ 19 листопада 2007 року у складі .NET Framework 3.5.

В C# 3.0 з'явилися такі радикальні доповнення та зміни:

  • Ключові слова select, from, where, що дозволяють робити запити з SQL, XML, колекції тощо (запит, інтегрований в мову — LINQ, англ. Language Integrated Query)
  • Ініціалізація об'єкта разом з його властивостями:
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 за генерованим MSIL-кодом; поліпшення в мові — чисто синтаксичні і реалізуються на етапі компіляції. Наприклад, багато з інтегрованих запитів LINQ можна реалізувати в поточних версіях використовуючи безіменні делегати в поєднанні з предикативними методами над контейнерами, на кшталт List.FindAll і List.RemoveAll.

Версія 4.0[ред. | ред. код]

Випуск четвертої версії мови програмування C# не випадково співпав з випуском нової версії .NET Framework. Він мав на меті створення інфраструктури для реалізації мов динамічної типізації. Що суттєво поліпшило підтримку динамічних API в C# [5], було бажаним для початку робіт над мовою TypeScript та було використано наявними реалізаціями, наприклад PowerShell[6].

Нові можливості в версії 4.0:

// Так робили виклик методів 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 Interop" — позбавило розробників клопоту з поставкою PIA[7]

Версія 5.0[ред. | ред. код]

Версія 6.0[ред. | ред. код]

Версія 7.0[ред. | ред. код]

Версія 8.0[ред. | ред. код]

C# 8.0 доступний на .NET Core 3.x та .NET Standard 2.1.

Тільки для читання[ред. | ред. код]

Ви можете застосувати модифікатор лише для читання до членів структури. Це вказує, що він не змінюватиме стан. Це більш детально, ніж застосування модифікатора readonly до декларації усієї структури. Наприклад:

public readonly override string ToString() =>     $"({X}, {Y}) це {Distance} від початку"; 

Версія 9.0[ред. | ред. код]

C# 9.0 доступний лише на .NET 5.

Записові типи (англ. Record types)[ред. | ред. код]

Посилальні типи що мають семантику значених типів для перевірки рівності [2] [Архівовано 5 вересня 2020 у Wayback Machine.]. Це досягається за допомогою реалізації методів порівняння та обчислення хешу аналогічно до значених типів. Записові типи за визначенням незмінні.
Приклад записового типу, що представляє точку на декартовій системі координат:

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# має «препроцесорні директиви»[8] (хоча насправді він не має препроцесора) на основі препроцесора C, це дає програмісту можливість визначити символи, але не макроси. Умовні директиви, такі як #if, #endif, чи #else також можливі. Директиви типу #region дають натяк редактору для згортання фрагментів коду.

Бібліотеки[ред. | ред. код]

Специфікація C# визначає мінімальний набір бібліотек типів і класів, на який має розраховувати компілятор. На практиці, C# найчастіше використовується з якоюсь реалізацією Common Language Infrastructure[en] (CLI), яка стандартизована як ECMA-335 Common Language Infrastructure (CLI).

Стандартизація[ред. | ред. код]

C# стандартизований в ECMA[9] та ISO[10].

У серпні 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), які випускають патентні права публічно[11]. Але є деякі застереження і обговорення про те, що існують додаткові аспекти, патентовані Microsoft, що не покриті, які можуть утримувати незалежних реалізаторів повного фреймворку.

Microsoft також погодився не позиватися проти розробників відкритого програмного забезпечення щодо порушення прав у неприбуткових проєктах для частини свого фреймворку, покритого OSP[12]. Microsoft погодився не порушувати патентних вимог щодо продуктів Novell проти платних клієнтів Novell[13] за винятком переліку продуктів, що явно не згадують C#, .NET чи реалізацію .NET від Novell (проєкт Mono)[14]. Проте Novell дотримується точки зору, що Mono не порушує жодного патенту Microsoft.[15]. Microsoft також уклав спеціальну угоду не позиватися проти браузерного плагіну Moonlight, який спирається на Mono, отриманного від Novell.[16]

У зауваженні, опублікованому на сайті новин Free Software Foundation у червні 2009 Річард Столлман попереджає, що він вважає, що «Microsoft можливо планує одного дня оголосити всі вільні реалізації C# такими, що використовують програмні патенти» і рекомендував розробникам уникати того, що він називає «безвідплатним ризиком», пов'язаним із «залежністю вільних реалізацій C#»[17]. Free Software Foundation пізніше повторила свої попередження[18], стверджуючи, що розширення Microsoft Community Promise на специфікації ECMA C# і CLI[19] можуть не вберігти від шкідництва 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 [Архівовано 12 жовтня 2019 у Wayback Machine.], який використовується як альтернатива 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 також надає відкритий компілятор C#, близьку до повної реалізацію Common Language Infrastructure, включаючи потрібні бібліотеки фреймворка відповідно до специфікації ECMA, і підмножину деяких залишених власницьких біліотек класів Microsoft .NET до .NET 2.0 (які не документовані або не включені у специфікації ECMA, але включені у стандартне визначення Microsoft .NET Framework).
  • DotNetAnywhere [Архівовано 4 травня 2009 у Wayback Machine.] Micro Framework Common Language Runtime націлений на вбудовані системи, і підтримує майже всі специфікації C# 2.0.

Приклад «Hello, world!»[ред. | ред. код]

using System;  class ExampleClass {   static void Main()   {     Console.WriteLine("Hello, world!");     Console.ReadKey();   } } 

У версії C# 9.0 з'явилась можливість написання програм з неявно визначеним методом Main:

using System;  Console.WriteLine("Hello, world!"); Console.ReadKey(); 

Діалекти[ред. | ред. код]

Spec#[ред. | ред. код]

Spec# – формальна мова для API контрактів, яка розширює C# конструкціями для не нульових типів, передумов, постумов та інваріантів об'єктів. Впроваджена у 2003 році в рамках проекту Microsoft Research[20].

Sing#[ред. | ред. код]

Sing# — мова програмування, розроблена на основі Spec# у рамках проекту Singularity. Це розширення C#, яке забезпечує перевірювану, повноцінну підтримку примітивів ОС для комунікації та сильну підтримку для системного програмування та факторизації коду[джерело?].

Див. також[ред. | ред. код]

Примітки[ред. | ред. код]

  1. Welcome to C# 11. 8 листопада 2022. Процитовано 26 вересня 2023.
  2. Як зробити посилання на інший рядок в C #?. Архів оригіналу за 13 грудня 2019.
  3. Архівована копія. Архів оригіналу за 7 серпня 2005. Процитовано 31 жовтня 2007.{{cite web}}: Обслуговування CS1: Сторінки з текстом «archived copy» як значення параметру title (посилання)
  4. Архівована копія. Архів оригіналу за 17 травня 2008. Процитовано 31 жовтня 2007.{{cite web}}: Обслуговування CS1: Сторінки з текстом «archived copy» як значення параметру title (посилання)
  5. Новые средства C# в .NET Framework 4. msdn.microsoft.com (ru-ru) . 1 жовтня 2010. Архів оригіналу за 7 серпня 2019. Процитовано 7 серпня 2019.
  6. PowerShell 3 – Finally on the DLR!. web.archive.org (en-us) . 28 квітня 2012. Архів оригіналу за 28 квітня 2012. Процитовано 7 серпня 2019.
  7. Deploying an Interop Application. docs.microsoft.com (en-us) . Архів оригіналу за 7 серпня 2019. Процитовано 7 серпня 2019.
  8. C# Preprocessor Directives. Архів оригіналу за 4 липня 2008. Процитовано 27 лютого 2009.
  9. Standard ECMA-334 C# Language Specification, 4rd edition (June 2006). Архів оригіналу за 31 жовтня 2010. Процитовано 31 жовтня 2007.
  10. ISO/IEC 23270:2003, Information technology — C# Language Specification. Архів оригіналу за 30 червня 2006. Процитовано 31 жовтня 2007.
  11. Interoperability Principles. Архів оригіналу за 22 червня 2013. Процитовано 4 травня 2010.
  12. Patent Pledge for Open Source Developers. Архів оригіналу за 22 червня 2013. Процитовано 4 травня 2010.
  13. Patent Cooperation Agreement - Microsoft & Novell Interoperability Collaboration. Microsoft. 2 листопада 2006. Архів оригіналу за 22 червня 2013. Процитовано 5 липня 2009. Microsoft, on behalf of itself and its Subsidiaries (collectively “Microsoft”), hereby covenants not to sue Novell’s Customers and Novell’s Subsidiaries’ Customers for infringement under Covered Patents of Microsoft on account of such a Customer’s use of specific copies of a Covered Product as distributed by Novell or its Subsidiaries (collectively “Novell”) for which Novell has received Revenue (directly or indirectly) for such specific copies; provided the foregoing covenant is limited to use by such Customer (i) of such specific copies that are authorized by Novell in consideration for such Revenue, and (ii) within the scope authorized by Novell in consideration for such Revenue.
  14. Definitions. Microsoft. 2 листопада 2006. Архів оригіналу за 22 червня 2013. Процитовано 5 липня 2009.
  15. Steinman, Justin (7 листопада 2006). Novell Answers Questions from the Community. Архів оригіналу за 22 червня 2013. Процитовано 5 липня 2009. We maintain that Mono does not infringe any Microsoft patents.
  16. Covenant to Downstream Recipients of Moonlight — Microsoft & Novell Interoperability Collaboration. Microsoft. 28 вересня 2007. Архів оригіналу за 2 березня 2012. Процитовано 8 березня 2008. “Downstream Recipient” means an entity or individual that uses for its intended purpose a Moonlight Implementation obtained directly from Novell or through an Intermediate Recipient… Microsoft reserves the right to update (including discontinue) the foregoing covenant… “Moonlight Implementation” means only those specific portions of Moonlight 1.0 or Moonlight 1.1 that run only as a plug-in to a browser on a Personal Computer and are not licensed under GPLv3 or a Similar License.
  17. Stallman, Richard (26 червня 2009). Why free software shouldn't depend on Mono or C#. Free Software Foundation. Архів оригіналу за 22 червня 2013. Процитовано 2 липня 2009. The danger is that Microsoft is probably planning to force all free C# implementations underground some day using software patents. … We should systematically arrange to depend on the free C# implementations as little as possible. In other words, we should discourage people from writing programs in C#. Therefore, we should not include C# implementations in the default installation of GNU/Linux distributions, and we should distribute and recommend non-C# applications rather than comparable C# applications whenever possible.
  18. Microsoft's Empty Promise. Free Software Foundation. 16 липня 2009. Архів оригіналу за 22 червня 2013. Процитовано 2009-078-03. Until that happens, free software developers still should not write software that depends on Mono. C# implementations can still be attacked by Microsoft's patents: the Community Promise is designed to give the company several outs if it wants them. We don't want to see developers' hard work lost to the community if we lose the ability to use Mono, and until we eliminate software patents altogether, using another language is the best way to prevent that from happening.
  19. The ECMA C# and CLI Standards. 6 липня 2009. Архів оригіналу за 22 червня 2013. Процитовано 2009-078-03.
  20. Gubskiy, Andrew (4 квітня 2023). The C# Multiverse — the Singularity of Programming Languages. Medium (англ.). Процитовано 22 червня 2023.

Посилання[ред. | ред. код]