C#(произносится как «см. диез », как музыкальная нота C♯, но записывается с помощью знака числа ) является универсальным многопарадигмальным языком программирования, охватывающим строгая типизация, лексическая область видимости, императивная, декларативная, функциональная, универсальная, объектно-ориентированное (на основе класса ) и компонентно-ориентированное дисциплины программирования.
C # был разработан около 2000 года компанией Microsoft в рамках инициативы .NET, а затем утвержден в качестве международного стандарта Ecma (ECMA-334) в 2002 году и ISO (ISO / IEC 23270) в 2003 году. Он был разработан Андерсом Хейлсбергом, а его командой разработчиков в настоящее время глобет Мадс Торгерсен, являющимся одним из языков программирования, разработанных для Common Language Infrastructure. (CLI). Самой последней версией 9.0, выпущенной в 2020 году в.NET 5.0 и включенной в Visual Studio 2019 версии 16.8.
Mono - это бесплатный проект с открытым исходным кодом для разработки кроссплатформенный компилятор и среда выполнения (т.е. виртуальная машина ) для языка.
В стандарте Ecma следующие цели разработки для C #:
Во время разработки.NET Framework классов библиотеки изначально писались на спой управляемый код компилятор системы под названием "Simple Managed C" (SMC). В январе 1999 года Андерс Хейлсберг сформировал команду для создания нового в то время языка под названием Cool, который расшифровывался как «C-подобный объектно-ориентированный язык». Microsoft рассматривала возможность названия названия «Cool» в качестве окончательного названия языка. К тому времени, когда проект.NET был публично объявлен на конференции профессиональных разработчиков в июле 2000 г., язык был переименован в C #, а библиотеки классов и среда выполнения ASP.NET были перенесены на C #.
Хейлсберг - главный разработчик C # и ведущий архитектор в Microsoft, ранее участвовал в разработке Turbo Pascal, Embarcadero Delphi (ранее CodeGear Delphi, Inprise Delphi и Borland Delphi) и Visual J ++. В интервью и статьях он заявляет о недостатках большинства языков программирования (например, C ++, Java, Delphi и Smalltalk ) положил начало основам Common Language Runtime (CLR), что, в свою очередь, положило начало разработке самого языка C #.
Джеймс Гослинг, создавший язык программирования Java в 1994 году, и Билл Джой, соучредитель Sun Microsystems, создатель Java, названный C # « имитацией »Java; Гослинг далее сказал, что «[C #] является разновидностью Java, в которой установлены надежность, производительность и безопасность». Клаус Крефт и Анжелика Лангер (авторы книги о потоках C ++) заявили в своем блоге, что «Java и C # - почти идентичные языки программирования. Скучное повторение без инноваций »:« Кто-то утверждал, что Java или C # являются революционными языками программирования, которые изменили способ написания программ », и« C # многое позаимствовал у Java - и наоборот. Теперь, когда C # поддерживает упаковку и распаков, у нас будет очень похожая функция в Java ». В июле 2000 г. Хейлсберг заявил, что C # «не является клоном Java» и «намного ближе к C ++» по своей конструкции.
С момента выпуска C # 2.0 в ноябре 2005 г. языки C # и Java эволюционировали. по все более расходящимся траекториям, превращаясь в два совершенно разных языка. Одним из первых серьезных отклонений стало добавление дженериков к обоим языкам с совершенно разными реализациями. C # использует реи передачу для предоставления «первоклассных» универсальных объектов, которые можно использовать, как и любой другой класс, с генерацией кода , выполняемой во время загрузки класса. Кроме того, в C # добавлено несколько основных функций для поддержки программирования в функциональном стиле, кульминацией воспроизведения стали расширения LINQ, выпущенных вместе с C # 3.0, и поддерживающая его среда лямбда-выражений, методы расширения и анонимные типы. Эти функции позволяют программистам на C # использовать методы функционального программирования, такие как замыкания, когда это выгодно для их приложения. Расширения LINQ и функциональный инструмент позволяют использовать инструмент сокращения шаблонного кода, который включается в общие задачи, такие как запрос к базе данных, синтаксический анализ XML-файла или поиск в структуре данных, смещающая акцент на фактическую логика программы, помогающая улучшить читаемость и удобство обслуживания.
В C # раньше был талисман по имени Энди (названный в честь Андерса Хейлсберга). Он был удален 29 января 2004 г.
C # был представлен на рассмотрении подкомитету ISO JTC 1 / SC 22 в соответствии с ISO / IEC 23270: 2003, был отозван и утвержден в соответствии с ISO / IEC 23270: 2006.
Microsoft впервые использовала имя C # в 1988 году для варианта языка C, предназначенного для инкрементной компиляции. Этот проект не был завершен, но имя живет.
Музыкальная нота до-диезНазвание «До-диез» было навеяно нотной грамотой, где символ диез указывает, что написанная нота должна быть сделана на полутон выше с шагом . Это похоже на название языка C ++, где «++» указывает, что переменная должна быть увеличена на 1 после оценки. Острый символ также напоминает лигатуру из четырех символов «+» (в сетке два на два), что подразумевает, что язык является инкрементом C ++.
Из-за технических характеристик представления (стандартные шрифты, браузеры и т. Д.) И тот факт, что острый символ (U + 266F ♯ MUSIC SHARP SIGN (HTML ♯
·♯
)) не присутствует на большинстве раскладок клавиатуры, числовой знак (U + 0023 # НОМЕРНЫЙ ЗНАК (HTML #
·#
)) был выбирается для приближения важного символа в письменном названии языка программирования. Это соглашение отражено в спецификации языка C # ECMA-334.
Суффикс «резкий» использовался рядом с другими языками.NET, которые используют варианты использования языков, включая J # (язык.NET, также используемый Microsoft, который является производным от Java 1.1), A # (от Ada ) и язык функционального программирования F #. Первоначальная реализация Eiffel для.NET называлась Eiffel #, это название было отменено, поскольку теперь поддерживается полный язык Eiffel. Суффикс также использовался для библиотек, таких как Gtk # (оболочка.NET для GTK + и других GNOME библиотеки) и Какао # (оболочка для Какао ).
readonly struct
membersswitch
выраженияс использованием
объявленийстатических
локальных функцийref struct
GetEnumerator
поддержка циклов foreach
Основной синтаксис языка C # аналогичный синтаксису других языков C-стиля, таких как C, C ++ и Java, в частности:
Некоторые примечательные особенности C #, которые отличают его от C, C ++ и Java, где указаны таковы:
По дизайну C # является языком программирования, наиболее непосредственно используемым базовую инфраструктуру общего языка (интерфейс командной строки). Большинство его внутренних типов соответствуют типам значений, реализованным инфраструктурным интерфейсом командной строки. Однако в спецификации языка не указываются требования компилятора генерации кода: то есть не указывается, что компилятор C # должен нацеливаться на Common Language Runtime, или генерировать Common Intermediate Language (CIL), или генерировать любой другой конкретный формат. Теоретически компилятор C # мог бы генерировать машинный код, как компиляторы C ++ или Fortran.
C # Поддерживает строго типизированные объявления неявных чисел с ключевыми словами var
и неявно типизированные массивы с ключевым словом new
, за которым следует инициализатор коллекции.
C # поддерживает строгий логический тип данных, bool
. Операторы, которые принимают условия, такие как while
и if
, требуют выражения типа реализующего оператора true
, например типа Boolean. Хотя C ++ также имеет логический тип, его можно свободно преобразовывать в целые числа и обратно, а такие выражения, как if (a)
, требуют только того, чтобы a
был преобразован в bool, что позволяет a
быть int или указателем. C # запрещает этот подход «целое число, означающее истину или ложь» на том основании, что принуждение программистов использования выражений, возвращающих точно bool
, может представить типы ошибок программирования, такие как if (a = b)
(использование присвоения =
вместо равенства ==
).
C # более типобезопасен, чем C ++. Единственные неявные преобразования по умолчанию - это те, которые считаются безопасными, например расширение целых чисел. Это применяется во время компиляции, во время JIT и, в некоторых случаях, во время выполнения. Не происходит неявных преобразований между логическими значениями и целыми числами, а также между членами перечисления и целыми числами (за исключением литерала 0, который может быть неявно преобразован в любой перечислимый тип). Любое определяемое пользователем преобразование должно быть явно помечено как явное или неявное, в отличие от конструкторов копирования и операторов преобразования C ++ , которые по умолчанию являются неявными.
C # имеет явную поддержку ковариации и контравариантности в универсальных типах, в отличие от C ++, который имеет некоторую степень поддержки контравариантности просто через семантику возвращаемых типов в виртуальных методах.
Элементы перечисления помещаются в свою собственную область действия.
. Язык C # не допускает глобальных переменных или функций. Все методы и члены должны быть объявлены внутри классов. Статические члены публичных классов могут заменять глобальные переменные и функции.
Локальные переменные не могут затенять переменные охватывающего блока, в отличие от C и C ++.
Метапрограммирование с помощью атрибутов C # является частью языка. Многие из этих атрибутов дублируют функциональные возможности директив препроцессора GCC и VisualC ++, зависящих от платформы.
Метод в C # - это член класса, который может быть вызван как функция (последовательность инструкций), а не просто способность класса удерживать значение свойство. Как и в других синтаксически подобных языках, таких как C ++ и ANSI C, сигнатура метода представляет собой объявление, содержащее в порядке: любые необязательные ключевые слова доступности (такие как private
), явные спецификация его возвращаемого типа (например, int
или ключевое слово void
, если значение не возвращается), имя метода и, наконец, заключенная в скобки последовательность параметров, разделенных запятыми спецификации, каждая из которых состоит из типа параметра, его формального имени и, необязательно, значения по умолчанию, которое будет использоваться всякий раз, когда ничего не указано. Определенные конкретные виды методов, например те, которые просто получают или устанавливают свойство класса посредством возвращаемого значения или присваивания, не требуют полной подписи, но в общем случае определение класса включает полное объявление подписи его методов.
Подобно C ++ и в отличие от Java, программисты на C # должны использовать ключевое слово модификатора области virtual
, чтобы разрешить переопределение методов подклассами.
Методы расширения в C # позволяют программистам использовать статические методы, как если бы они были методами из таблицы методов класса, позволяя программистам добавлять методы к объекту, который, по их мнению, должен существовать для этого объекта и его производных.
Тип динамический
допускает привязку методов во время выполнения, что позволяет использовать вызовы методов, подобные JavaScript, и композицию объектов во время выполнения.
C # поддерживает строго типизированные указатели на функции через ключевое слово делегат
. Подобно сигналу и слоту псевдо-C ++ фреймворка Qt, C # имеет семантику, специально относящуюся к событиям стиля публикации-подписки, хотя C # использует для этого делегаты.
C # предлагает Java-подобные синхронизированные
вызовы методов через атрибут [MethodImpl (MethodImplOptions.Synchronized)]
и поддерживает взаимоисключающие блокировки. с помощью ключевого слова lock
.
C # поддерживает класс со свойствами . Свойства могут быть простыми функциями доступа с резервным полем или реализовывать функции получения и установки.
Начиная с C # 3.0 доступен синтаксический сахар автоматически реализуемых свойств, где метод доступа (геттер) и мутатор (сеттер) инкапсулируют операции с одним атрибут класса.
AC # пространство имен
обеспечивает тот же уровень изоляции кода, что и пакет Java или пространство имен C ++
, с правилами и функциями, очень похожими на
пакет
. Пространства имен могут быть импортированы с использованием синтаксиса.
В C # указатели адресов памяти могут использоваться только в блоках, специально помеченных как небезопасные, а программам с небезопасным кодом требуются соответствующие разрешения бежать. Большая часть доступа к объектам осуществляется через безопасные ссылки на объекты, которые всегда либо указывают на «живой» объект, либо имеют четко определенное значение null ; невозможно получить ссылку на «мертвый» объект (объект, который был собран сборщиком мусора) или на случайный блок памяти. Небезопасный указатель может указывать на экземпляр «неуправляемого» типа значения, который не содержит ссылок на объекты, массив, строку или блок выделенной стеком памяти, собранные сборщиком мусора. Код, который не помечен как небезопасный, по-прежнему может хранить указатели и управлять ими с помощью типа System.IntPtr
, но не может разыменовать их.
Управляемая память не может быть освобождена явно; вместо этого он автоматически собирает мусор. Сборка мусора решает проблему утечек памяти, освобождая программиста от ответственности за освобождение памяти, которая больше не нужна в большинстве случаев. Код, который сохраняет ссылки на объекты дольше, чем требуется, может по-прежнему использовать больше памяти, чем необходимо, однако после освобождения последней ссылки на объект память становится доступной для сборки мусора.
Программистам доступен ряд стандартных исключений. Методы в стандартных библиотеках при некоторых обстоятельствах регулярно вызывают системные исключения, и диапазон генерируемых исключений обычно документируется. Пользовательские классы исключений могут быть определены для классов, позволяющих применять конкретную обработку для конкретных обстоятельств по мере необходимости.
Проверенные исключения отсутствуют в C # (в отличие от Java). Это было осознанное решение, основанное на вопросах масштабируемости и версии.
В отличие от C ++, C # не поддерживает множественное наследование, хотя класс может реализовывать любое количество интерфейсов . Это дизайнерское решение было принято ведущим архитектором языка, чтобы избежать сложностей и упростить архитектурные требования во всем интерфейсе командной строки.
При реализации нескольких интерфейсов, содержащих метод с тем же именем и принимающих параметры одного и того же типа в одном порядке (т.е. с одинаковой сигнатурой), аналогично Java, C # позволяет как единый метод для покрытия всех интерфейсов и, при необходимости, специальные методы для каждого интерфейса.
Однако, в отличие от Java, C # поддерживает перегрузку оператора . Только наиболее часто перегружаемые операторы C ++ могут быть перегружены в C #.
C # имеет возможность использовать LINQ через.NET Framework. Разработчик может запрашивать различные источники данных при условии, что на объекте реализован интерфейс IEnumerable
. Сюда входят документы XML, набор данных ADO.NET и базы данных SQL.
Использование LINQ в C # дает такие преимущества, как поддержка Intellisense, сильные возможности фильтрации, безопасность типов с возможностью проверки ошибок компиляции и единообразие для запросов данных из различных источников. Существует несколько различных языковых структур, которые можно использовать с C # и LINQ, и это выражения запросов, лямбда-выражения, анонимные типы, неявно типизированные переменные, методы расширения и инициализаторы объектов.
Хотя в первую очередь императивный язык, C # 2.0 предлагал ограниченную поддержку функционального программирования посредством функций первого класса и замыканий в форме анонимных делегатов. В C # 3.0 расширена поддержка функционального программирования за счет введения облегченного синтаксиса для лямбда-выражений, методов расширения (возможность для модулей) и синтаксиса понимания списка в форме языка «понимания запросов». В C # 7.0 добавлены функции, типичные для функциональных языков, такие как кортежи и сопоставление с образцом.
В C # есть унифицированная система типов. Эта унифицированная система типов называется Common Type System (CTS).
Унифицированная система типов подразумевает, что все типы, включая примитивы, такие как целые числа, являются подклассами System.Object
класс. Например, каждый тип наследует метод ToString ()
.
CTS разделяет типы данных на две категории:
Экземпляры типов значений не имеют ни ссылочной идентичности, ни ссылочной семантика сравнения. Сравнение равенства и неравенства для типов значений сравнивает фактические значения данных в экземплярах, если соответствующие операторы не перегружены. Типы значений являются производными от System.ValueType
, всегда имеют значение по умолчанию и всегда могут быть созданы и скопированы. Некоторые другие ограничения типов значений состоят в том, что они не могут быть производными друг от друга (но могут реализовывать интерфейсы) и не могут иметь явного конструктора по умолчанию (без параметров). Примерами типов значений являются все примитивные типы, такие как int
(32-разрядное целое число со знаком), float
(32-разрядное число с плавающей запятой IEEE), char
(16-битная кодовая единица Unicode) и System.DateTime
(идентифицирует конкретный момент времени с точностью до наносекунды). Другие примеры: enum
(перечисления) и struct
(определяемые пользователем структуры).
Напротив, ссылочные типы имеют понятие ссылочной идентичности, что означает, что каждый экземпляр ссылочного типа по своей сути отличается от любого другого экземпляра, даже если данные в обоих экземплярах одинаковы. Это отражается в сравнениях равенства и неравенства по умолчанию для ссылочных типов, которые проверяют ссылочное, а не структурное равенство, если только соответствующие операторы не перегружены (например, в случае для System.String
). Некоторые операции не всегда возможны, например создание экземпляра ссылочного типа, копирование существующего экземпляра или выполнение сравнения значений на двух существующих экземплярах. Хотя определенные ссылочные типы могут предоставлять такие услуги, открывая открытый конструктор или реализуя соответствующий интерфейс (например, ICloneable
или IComparable
). Примерами ссылочных типов являются объект
(конечный базовый класс для всех других классов C #), System.String
(строка символов Юникода) и System.Array
(базовый класс для всех массивов C #).
Обе категории типов могут быть расширены с помощью типов, определяемых пользователем.
Упаковка - это операция преобразования объекта типа значения в значение соответствующего ссылочного типа. Бокс в C # неявный.
Распаковка - это операция преобразования значения ссылочного типа (ранее помещенного в рамку) в значение типа значения. Для распаковки в C # требуется явное приведение типа . Упакованный объект типа T можно распаковать только в T (или T, допускающий значение NULL).
Пример:
int foo = 42; // Тип значения. объект bar = foo; // foo помещается в бар. int foo2 = (int) bar; // Распаковка обратно в тип значения.
Спецификация C # описывает минимальный набор типов и библиотек классов, которые, как ожидает компилятор, будут доступны. На практике C # чаще всего используется с некоторой реализацией Common Language Infrastructure (CLI), которая стандартизирована как Common Language Infrastructure (CLI) ECMA-335.
В дополнение к стандартным спецификациям интерфейса командной строки существует множество коммерческих и общественных библиотек, которые строятся на основе библиотек.NET framework для обеспечения дополнительных функций.
C # может выполнять вызовы любой библиотеки включен в Список библиотек и фреймворков.NET.
Ниже приводится очень простая программа на C #, версия классической "Hello world "пример:
using System; // Версия классической программы "Hello World". Класс Program {public static void Main (string args) {Console.WriteLine ("Hello, world!"); }}
Этот код отобразит этот текст в окне консоли:
Привет, мир!
Каждая строка имеет цель:
использование системы;
Строка выше импортирует все типы в пространство имен System
. Например, класс Console
, используемый позже в исходном коде, определен в пространстве имен System
, то есть его можно использовать без предоставления полного имени типа (которое включает пространство имен).
// Версия классической программы "Hello World"
Эта строка является комментарием; он описывает и документирует код для программиста (ов).
класс Program
Выше - определение class для класса Program
. Все, что следует между парой скобок, описывает этот класс.
{...}
Фигурные скобки разграничивают границы блока кода. В этом первом случае они отмечают начало и конец класса Program
.
public static void Main (string args)
Объявляет метод члена класса, с которого программа начинает выполнение. The.NET runtime calls the Main
method. (Note: Main
may also be called from elsewhere, like any other method, e.g. from another method of Program
.) The public
keyword tells the compiler that the method can be called from anywhere by any class. The static keyword makes the method accessible without an instance of Program
. Each console application's Main
entry point must be declared static
otherwise the program would require an instance of Program
, but any instance would require a program. To avoid that irresolvable circular dependency, C# compilers processing console applications (like that above) report an error if there is no static Main
method. The void
keyword declares that Main
has no return value.
Console.WriteLine("Hello, world!");
This line writes the output. Console
is a static class in the System
namespace. It provides an interface to the standard input, output, and error streams for console applications. The program calls the Console
method WriteLine
, which displays on the console a line with the argument, the string "Hello, world!"
.
A GUI example:
using System; using System.Windows.Forms; class Program { static void Main () {MessageBox.Show ("Привет, мир!"); Console.WriteLine («Это почти тот же аргумент!»); }}
Этот пример аналогичен предыдущему, за исключением того, что он генерирует диалоговое окно, которое содержит сообщение «Hello, World!» вместо записи в консоль.
Еще одна полезная библиотека - это библиотека System.Drawing
, которая используется для программного рисования изображений. Например:
using System; с помощью System.Drawing; публичный класс Example {public static Image img; публичный статический void Main () {img = Image.FromFile ("Image.png"); }}
Это создаст изображение, идентичное тому, что хранится в "Image.png".
В августе 2001 года Microsoft Corporation, Hewlett-Packard и Intel Corporation совместно спонсировали предоставление спецификаций для C #, а также Common Language Infrastructure (CLI) в организацию по стандартизации Ecma International. В декабре 2001 года ECMA выпустила спецификацию языка C # ECMA-334. C # стал стандартом ISO в 2003 году (ISO / IEC 23270: 2003 - Информационные технологии - Языки программирования - C #). ECMA ранее приняла эквивалентные спецификации в качестве 2-го издания C # в декабре 2002 года.
В июне 2005 года ECMA утвердила издание 3 спецификации C # и обновила ECMA-334. Добавления включали частичные классы, анонимные методы, типы, допускающие значение NULL, и универсальные шаблоны (несколько похожие на шаблоны C ++ ).
В июле 2005 года ECMA представила в ISO / IEC JTC 1, через ускоренный процесс, стандарты и соответствующие TR. Обычно этот процесс занимает 6–9 месяцев.
Определение языка C # и CLI стандартизированы в соответствии со стандартами ISO и Ecma, которые обеспечивают разумное и недискриминационное лицензирование защита от патентных притязаний.
Microsoft согласилась не предъявлять иски разработчикам открытого исходного кода за нарушение патентов в некоммерческих проектах в отношении той части платформы, на которую распространяется OSP. Microsoft также согласилась не применять патенты, относящиеся к продуктам Novell, в отношении платежеспособных клиентов Novell, за исключением списка продуктов, в которых явно не упоминаются C #,.NET или реализация.NET от Novell (Моно проект ). Однако Novell утверждает, что Mono не нарушает никаких патентов Microsoft. Microsoft также заключила специальное соглашение не применять патентные права, связанные с подключаемым модулем браузера Moonlight, который зависит от Mono, при условии, что он получен через Novell.
Microsoft возглавляет разработку эталонных компиляторов C # с открытым исходным кодом и набора инструментов, первый компилятор Roslyn компилируется в промежуточный язык (IL), второй - RyuJIT, является JIT-компилятором (точно в срок), который представляет собой динамический и исполняющий обязанности по работе с кодом для внешнего интерфейса ЦП. RuyJIT имеет открытый исходный код и написан на C ++. Roslyn полностью написан на управляемым кодом (C #), был открыт и функциональность представлена в виде API. Таким образом, разработчики могут создать инструменты рефакторинга и диагностики. Две официальной реализации - это.NET (закрытые исходные коды, Windows 10 только с.NET 4.6.2) и ядро .NET (открытый исходный код, мультиплатформенность);.NET и ядро .NET объединяются в один вызов с открытым исходным кодом.NET 5.0. В.NET 4.6 новый JIT-компилятор заменил прежний.
Другие компиляторы C # (некоторые из которых используются Common Language Infrastructure и библиотек классов.NET):
Mono является обычным выбором для игровых движков из-за его кросс-платформенности. платформенный характер. Игровой движок Unity использует Mono C # в качестве основного языка сценариев. В игровой движок Godot реализован дополнительный модуль Mono C # благодаря пожертвованию в размере 24000 от Microsoft.
|
|
В Викиучебнике есть книга по теме: Программирование C Sharp |