Встроенные типы и литералы

Подсказка

Вы новичок в разработке программного обеспечения? Сначала начните с учебников для начинающих. Они вводят типы при написании первых программ.

Есть опыт на другом языке? Встроенные типы C# тесно соответствуют типам в Java, C++ и других языках. Просмотрите разделы синтаксиса литералов и вывод типов для получения сведений о C#.

C# предоставляет набор встроенных типов, которые можно использовать в любой программе без дополнительных ссылок. Эти типы охватывают наиболее распространенные данные, с которыми вы работаете: числа, значения true/false, отдельные символы и текст. Полная таблица ссылочного сопоставления ключевых слов C# с типами .NET доступна см. в разделе «Встроенные типы C# (справочник)».

Числовые типы

C# имеет встроенные типы для целых чисел, чисел с плавающей запятой и десятичных чисел. Наиболее часто используемые типы: intи doubledecimal:

int population = 67_000_000;
long distance = 384_400_000L;
short temperature = -40;
byte red = 255;

double pi = 3.141592653589793;
float gravity = 9.81f;
decimal price = 19.99m;

Каждый числовой тип имеет фиксированный размер и диапазон. int хранит 32-разрядные целые числа (примерно ±2,1 млрд), long хранит 64-разрядные целые числа и shortbyte сохраняет меньшие значения. Полный список размеров и диапазонов см. в разделе " Целочисленные числовые типы " и числовые типы с плавающей запятой.

Используется double для общей математики с плавающей запятой, float если память ограничена, а decimal также при необходимости точной десятичной точности (например, финансовых вычислений). Добавьте суффикс f для литералов float и m для литералов decimal. Без суффикса компилятор обрабатывает число как десятичную дробь double.

Неподписанные типы

Каждый целочисленный тип со знаком имеет аналог без знака, который сохраняет только неотрицательные значения с удвоенным положительным диапазоном.

uint fileSize = 4_294_967_295;
ulong totalBytes = 18_446_744_073_709_551_615;
ushort port = 443;

Вы можете использовать неподписанные типы, если отрицательные значения недопустимы для данных, например размеры файлов или сетевые порты. На практике многие приложения используют int или long даже для положительных значений, так как подписанные типы используются по умолчанию в API .NET.

Целые числа собственного размера

nint nuint Типы представляют целые числа, размер которых соответствует собственному размеру указателя платформы: 32 бита на 32-разрядной платформе, 64 бита на 64-разрядной платформе:

nint bufferSize = 1024;
nuint elementCount = 256;

Вряд ли вам потребуется nint или nuint в повседневном коде. Они существуют для сценариев взаимодействия между системами и операций с низкоуровневой памятью, где важен соответствующий размер указателя платформы. int или long придерживайтесь, если у вас нет определенной причины использовать типы, соответствующие размеру платформы. Дополнительные сведения см. в разделах nint и nuint.

bool, char и string

Помимо чисел, C# предоставляет три других часто используемых встроенных типа:

bool isValid = true;
char grade = 'A';
string greeting = "Hello, world!";
  • bool — хранит true или false. Используйте его в условиях, циклах и логических выражениях.
  • char — сохраняет один символ Юникода (единица кода UTF-16), заключенную в одинарные кавычки.
  • string — хранит последовательность символов, заключенную в двойные кавычки. Строки неизменяемы. После создания строки невозможно изменить его содержимое. Операции, которые, как представляется, изменяют строку, фактически создают новую.

Строки являются одним из наиболее используемых типов в C#. Подробное покрытие строковых операций, включая интерполяцию, необработанные строковые литералы, поиск, разделение и сравнение, см. в разделе "Строки ".

Синтаксис литерала

Литерал — это значение, которое вы пишете непосредственно в коде. Компилятор назначает каждому литералу тип в зависимости от его формата и любого предоставляемого вами суффикса. C# поддерживает следующие типы литералов:

  • Целые литералы — десятичные (42), шестнадцатеричные (0x2A) и двоичные (0b_0010_1010).
  • Литералы с плавающей запятойdouble по умолчанию (3.14), float с суффиксом f (3.14f), и decimal с m (3.14m).
  • Литералы символов — один символ в одинарных кавычках ('A'), включая escape-последовательности ('\n').
  • Строковые литералы — обычные ("hello"), дословные (@"C:\path"), необработанные (""" ... """) и интерполированные ($"value: {x}").
  • Логические литералыtrue и false.
  • Литерал null — обозначает отсутствие значения для ссылочных типов и типов значений, допускающих значение NULL.
  • Литерал default — создает значение по умолчанию для любого типа (описывается в выраженияхdefault).

В следующих разделах подробно рассматриваются наиболее распространенные литеральные формы.

Целочисленные литералы

int dec = 42;
int hex = 0x2A;
int bin = 0b_0010_1010;
long big = 1_000_000_000L;

0x Используйте префикс для шестнадцатеричного и 0b двоичного файла. Добавьте L для long, U для uint или UL для ulong.

_ Поместите разделитель цифр в любое место в пределах числа, чтобы упростить чтение. Распространенные шаблоны включают разделители тысяч в десятичных литералах (1_000_000_000), границы байтов или слов в шестнадцатеричных числах (0xFF_FF), а также границы полубайтов в двоичном выражении (0b_0010_1010).

Литералы с плавающей запятой

double d = 3.14;
float f = 3.14f;
decimal m = 3.14m;
double scientific = 1.5e6; // 1,500,000

Числовой литерал без суффикса с десятичной запятой double. Добавьте f для float и m для decimal. Также поддерживается научная нотация (1.5e6).

Символьные и строковые литералы

char newline = '\n';
char unicode = '\u0041'; // 'A'

string message = $"Found {dec} items";            // interpolated string
string path = @"C:\Users\docs\file.txt";        // verbatim string
string json = """
    { "name": "Alice", "age": 30 }
    """;                                           // raw string literal
string raw = $"""
    Found {dec} items in "{greeting}"
    """;                                           // raw + interpolated

Символьные литералы используют одинарные кавычки и поддерживают escape-последовательности (\n, \t, \u). Строковые литералы используют двойные кавычки.

Префиксируйте строки с $ для интерполяции. Если строка содержит кавычки, обратные слэши или внедренные JSON или XML, используйте необработанный строковый литерал (ограниченный """) вместо экранирования каждого символа. Необработанные строковые литералы также объединяются с интерполяцией ($""").

Старый код использует @ (подробные строки), чтобы избежать escape-обработки. Необработанные строковые литералы проще читать и записывать, поэтому предпочитают их для нового кода.

default Выражения

Выражение default создает значение по умолчанию для типа: 0 для числовых типов, false для bool, и null для ссылочных типов.

int defaultInt = default;          // 0
bool defaultBool = default;        // false
string? defaultString = default;   // null

// Use default in a conditional:
var limit = (args.Length > 0) ? int.Parse(args[0]) : default(int);

Выражение default наиболее полезно в универсальном коде, где вы не знаете конкретный тип и не можете жестко кодить определенное значение, например 0 или null. Напишите default (без аргумента типа), когда компилятор может выводить тип из контекста, либо default(T), когда тип не является очевидным. Полный список значений по умолчанию по типу см. в разделе "Значения по умолчанию" типов C#.

Неявно типизированные переменные с var

Ключевое var слово указывает компилятору выводить тип локальной переменной из инициализатора.

var count = 10;              // compiler infers int
var name = "C#";             // compiler infers string
var items = new List<int>(); // compiler infers List<int>

// var requires an initializer — the compiler needs a value to infer the type.
// The following line wouldn't compile:
// var unknown;

Переменная по-прежнему строго типизирована; var не делает его динамическим. Компилятор определяет тип во время компиляции и обеспечивает безопасность типов как обычно. Используйте var , когда тип очевиден с правой стороны, чтобы уменьшить визуальный шум. Прописывайте тип, когда это делает код понятнее. Дополнительные сведения см. в разделе "Неявно типизированные локальные переменные".

Типизированные по целевому типу new выражения

Если вы уже знаете целевой тип из контекста, например объявление переменной или параметр метода, можно опустить имя типа из new выражения:

List<string> names = new() { "Alice", "Bob", "Charlie" };
Dictionary<string, int> scores = new()
{
    ["Alice"] = 95,
    ["Bob"] = 87
};

Целевой тип new уменьшает повторение, если имя типа длинное или отображается в левой части назначения. Он работает в любом месте, где компилятор может определить целевой тип, включая аргументы метода и операторы возврата. Дополнительные сведения см. в оператореnew — целевой типnew.

Тип dynamic.

Тип dynamic обходит проверку типа во время компиляции. Компилятор выполняет операции с переменной dynamic во время выполнения.

dynamic value = 42;
Console.WriteLine(value.GetType()); // System.Int32

value = "Now I'm a string";
Console.WriteLine(value.GetType()); // System.String

// The compiler doesn't check operations on dynamic at compile time.
// Errors surface at run time instead.

Используйте dynamic при взаимодействии с COM-API, динамическими языками или сценариями с большим количеством отражения, в которых типы не известны во время компиляции. Избегайте использования dynamic в большинстве кода приложения, поскольку при использовании вы теряете безопасность на этапе компиляции. Ошибки, которые компилятор обычно перехватывает, становятся исключениями во время выполнения. Дополнительные сведения см. в разделе "Динамический тип".

См. также