Размер
Встроенные ссылочные типы (справочник по C#)
Play

Встроенные ссылочные типы (справочник по C#)

В C# есть ряд встроенных ссылочных типов. У них есть ключевые слова или операторы, которые являются синонимами типа в библиотеке .NET.

Тип object

Тип object является псевдонимом System.Object в .NET. В унифицированной системе типов C# все типы, стандартные и определяемые пользователем, ссылочные типы и типы значений напрямую или косвенно наследуются из System.Object. Переменным типа object можно назначать значения любого типа. Любой переменной object можно назначить значение по умолчанию с помощью литерала null . Если переменная типа значения преобразуется в объект, она считается упакованной. Если переменная типа object преобразуется в тип значения, она считается распакованной. Дополнительные сведения см. в разделе Упаковка-преобразование и распаковка-преобразование.

Тип string

Тип string представляет последовательность, состоящую из нуля или более символов в кодировке Юникод. string является псевдонимом для System.String в .NET.

Несмотря на то что string представляет собой ссылочный тип, операторы равенства == и != по определению сравнивают не ссылки, а значения объектов string . Это делает проверку равенства строк более интуитивно понятной. Пример:

Отображается значение True, а затем False, поскольку содержимое строк эквивалентно, однако a и b не относятся к одному и тому же экземпляру строки.

При этом создается строковый объект, содержащий слова "good morning".

Строки неизменяемы, т. е. содержимое созданного строкового объекта изменить нельзя, хотя синтаксис выглядит так, будто это возможно. Например, при написании кода компилятор фактически создает новый строковый объект для хранения новой последовательности символов, а затем этот новый объект назначается b . Память, выделенная для b (если он содержит строку h), затем доступна для сборки мусора.

Оператор [] позволяет предоставить к отдельным символам строки доступ только на чтение. Допустимые значения индекса начинаются с 0 и должны быть меньше, чем длина строки:

Также оператор [] можно использовать для итерации каждого символа в строке:

Строковые литералы имеют тип string и могут быть записаны в двух формах: в кавычках (") или в кавычках с префиксом @ . Строковые литералы в кавычках заключаются в двойные кавычки ("):

Строковые литералы могут содержать любые символьные литералы. Escape-последовательности включены. В следующем примере escape-последовательность \\ используется для получения обратной косой черты, \u0066 — для получения буквы f, и \n — для получения новой строки.

Escape-код \udddd (где dddd состоит из четырех цифр) представляет символ Юникода U+ dddd . Также распознаются восьмизначные escape-коды Юникода: \Udddddddd .

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

Преимущество буквальных строк состоит в том, что escape-последовательности не обрабатываются, что позволяет легко написать, например, полное имя файла Windows:

Чтобы добавить в строку @-quoted двойные кавычки, продублируйте этот символ:

Тип delegate

Объявление типа делегата аналогично сигнатуре метода. Оно имеет возвращаемое значение и любое число параметров любого типа:

В .NET типы System.Action и System.Func предоставляют общие определения для многих распространенных делегатов. Скорее всего, не нужно определять новые пользовательские типы делегата. Вместо этого можно создать экземпляры предоставленных универсальных типов.

Ключевое слово delegate имеет ссылочный тип, который можно использовать для инкапсуляции именованного или анонимного метода. Делегаты аналогичны используемым в языке C++ указателям функций, но являются типобезопасными и безопасными. Сведения о применении делегатов см. в разделах Делегаты и Универсальные делегаты. Делегаты являются основой событий. Экземпляры делегата могут создаваться путем его связывания с именованным или анонимным методом.

Делегат должен быть создан при помощи метода или лямбда-выражения, имеющего совместимые возвращаемый тип и входные параметры. Дополнительные сведения о допустимой степени вариации сигнатур методов см. в разделе Вариативность в делегатах. Для использования с анонимными методами делегат и код, который должен быть связан с ним, должны быть объявлены вместе.

Комбинирование и удаление делегата завершаются ошибкой из-за исключения среды выполнения, когда типы делегатов, задействованные во время выполнения, отличаются из-за преобразования вариантов. В следующем примере показана ситуация, в которой происходит сбой:

Вы можете создать делегат с правильным типом среды выполнения, создав новый объект делегата. В следующем примере показано, как это решение можно применить к предыдущему примеру.

Начиная с C# 9, можно объявить указатели функций, которые используют аналогичный синтаксис. Указатель функции использует инструкцию calli вместо создания экземпляра типа делегата и вызова виртуального метода Invoke .

Тип dynamic

Тип dynamic указывает, что использование переменной и ссылок на ее члены обходит проверку типа во время компиляции. Такие операции разрешаются во время выполнения. Тип dynamic упрощает доступ к API COM, таким как API автоматизации Office, к динамическим API, таким как библиотеки IronPython, и к HTML-модели DOM.

Тип dynamic в большинстве случаев ведет себя как тип object . В частности, можно преобразовать любое выражение, отличное от NULL, в тип dynamic . Тип dynamic отличается от object тем, что операции, которые содержат выражения типа dynamic , не разрешаются или тип проверяется компилятором. Компилятор объединяет сведения об операции, которые впоследствии будут использоваться для оценки этой операции во время выполнения. В рамках этого процесса переменные типа dynamic компилируются в переменные типа object . Таким образом, тип dynamic существует только во время компиляции, но не во время выполнения.

В следующем примере переменной типа dynamic противопоставляется переменная типа object . Чтобы проверить тип каждой переменной во время компиляции, наведите указатель мыши на dyn или obj в операторах WriteLine . Скопируйте следующий код в редактор, где доступен IntelliSense. IntelliSense отображает dynamic для dyn и object для obj .

Операторы WriteLine отображают типы времени выполнения dyn и obj . На этом этапе оба имеют один и тот же тип — целое число. Выводятся следующие результаты.

Чтобы увидеть разницу между dyn и obj во время компиляции, добавьте между объявлениями и операторами WriteLine в предыдущем примере следующие две строки:

При попытке добавления целого числа и объекта в выражение obj + 3 выдается ошибка компилятора. При этом для dyn + 3 ошибка не возникает. Выражение, которое содержит dyn , не проверяется во время компиляции, поскольку тип dyn имеет значение dynamic .

В следующем примере dynamic используется в нескольких объявлениях. Метод Main также противопоставляет проверку типов во время компиляции.

📎📎📎📎📎📎📎📎📎📎