Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Подсказка
Вы новичок в разработке программного обеспечения? Сначала начните с учебников для начинающих. Они ведут вас шаг за шагом по процессу написания программ и по ходу дела объясняют типы.
Есть опыт на другом языке? Если вы уже понимаете системы типов, пропустите различия между значением и ссылкой и выберите руководство по типам, а затем перейдите к статьям по определенным типам.
C# — это строго типизированный язык. Каждая переменная, константа и выражение имеют тип. Компилятор применяет безопасность типов , проверяя, является ли каждая операция в коде допустимой для используемых типов. Например, можно добавить два int значения, но нельзя добавить и int :bool
int a = 5;
int b = a + 2; // OK
bool test = true;
// Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'.
// int c = a + test;
Замечание
В отличие от C и C++, в C#, bool не преобразуется в int.
Безопасность типов обнаруживает ошибки на этапе компиляции до выполнения вашего кода. Компилятор также внедряет сведения о типе в исполняемый файл в виде метаданных, которые среда CLR использует для дополнительных проверок безопасности во время выполнения.
Объявление переменных с типами
При объявлении переменной вы указываете его тип явным образом или используете var , чтобы компилятор выводил тип из назначенного значения:
// Explicit type:
int count = 10;
double temperature = 36.6;
// Compiler-inferred type:
var name = "C#";
var items = new List<string> { "one", "two", "three" };
Параметры метода и возвращаемые значения также имеют типы. Следующий метод принимает string и intвозвращает string:
static string GetGreeting(string name, int visitCount)
{
return visitCount switch
{
1 => $"Welcome, {name}!",
_ => $"Welcome back, {name}! Visit #{visitCount}."
};
}
После объявления переменной нельзя изменить его тип или назначить значение, несовместимое с объявленным типом. Значения можно преобразовать в другие типы. Компилятор выполняет неявные преобразования , которые не теряют данные автоматически. Явные преобразования (приведения) требуют указания преобразования в коде. Для получения дополнительной информации см. Приведение и преобразование типов.
Встроенные типы и настраиваемые типы
C# предоставляет встроенные типы для общих данных: целых чисел, чисел с плавающей запятой, boolcharи string. Каждая программа C# может использовать эти встроенные типы без дополнительных ссылок.
Помимо встроенных типов, можно создать собственные типы с помощью нескольких конструкций:
- Классы — ссылочные типы для поведения моделирования и сложных объектов. Поддержка наследования и полиморфизма.
- Структуры — типы значений для небольших, упрощенных данных. Каждая переменная содержит собственную копию.
-
Записи — классы или структуры с равенством, созданным компилятором,
ToStringи недеструктивная мутация с помощьюwithвыражений. - Интерфейсы — контракты, которые определяют элементы, которые могут быть реализованы любым классом или структурой.
- Перечисления — именованные наборы целочисленных констант, такие как дни недели или режимы доступа к файлам.
- Кортежи — упрощенные структурные типы, которые группирует связанные значения без определения именованного типа.
-
Универсальные шаблоны — типо-параметризованные конструкции, такие как
List<T>иDictionary<TKey, TValue>обеспечивающие безопасность типов при повторном использовании одной логики для разных типов.
Типы значений и ссылочные типы
Каждый тип в C# — это тип значения или ссылочный тип. Это различие определяет, как переменные хранят данные и как работает назначение.
Типы значений хранят данные напрямую. При назначении типа значения новой переменной среда выполнения копирует данные. Изменения в одной переменной не влияют на другую. Структуры, перечисления и встроенные числовые типы являются всеми типами значений.
Ссылочные типы хранят ссылку на объект, находящийся в управляемой памяти. При назначении ссылочного типа новой переменной оба переменных указывают на один и тот же объект. Изменения через одну переменную отображаются через другую. Классы, массивы, делегаты и строки являются ссылочными типами.
В следующем примере показано различие. Первый блок показывает определение структуры Coords записи, которая является типом значения. Второй блок демонстрирует различное поведение для типов значений и ссылочных типов.
public readonly record struct Coords(int X, int Y);
// Value type: each variable holds its own copy
var point1 = new Coords(3, 4);
var point2 = point1;
Console.WriteLine($"point1: ({point1.X}, {point1.Y})");
Console.WriteLine($"point2: ({point2.X}, {point2.Y})");
// point1 and point2 are independent copies
// Reference type: both variables refer to the same object
var list1 = new List<int> { 1, 2, 3 };
var list2 = list1;
list2.Add(4);
Console.WriteLine($"list1 count: {list1.Count}"); // 4 — same object
Все типы в конечном счете являются производными от System.Object. Типы значений происходят от System.ValueType, который, в свою очередь, происходит от object. Эта унифицированная иерархия называется common Type System (CTS). Дополнительные сведения о наследовании см. в разделе "Наследование".
Выберите тип типа
При определении нового типа, тип, который вы выбираете, влияет на поведение вашего кода. Используйте следующие рекомендации, чтобы принять первоначальное решение:
- Кортеж — временное группирование значений, которое не требует именованного типа или поведения.
-
structилиrecord struct— небольшие данные (примерно 64 байта или меньше), семантика значений или неизменяемость. Структуры записи добавляют поддержку равенства на основе значений иwithвыражений. -
record class— в первую очередь данные с равенством на основе значений,ToStringа также недеструктивной мутацией. Поддерживает наследование. -
class— сложное поведение, полиморфизм или изменяемое состояние. Большинство пользовательских типов — это классы. -
interface— контракт, который могут реализовать несвязанные типы. Определяет возможности, а не личность. -
enum— фиксированный набор именованных констант, например коды состояния или параметры.
Более одного варианта часто является разумным.
Тип времени компиляции и тип времени выполнения
Переменная может иметь различные типы во время компиляции и во время выполнения. Тип времени компиляции — это объявленный или выводемый тип в исходном коде. Тип времени выполнения — это фактический тип экземпляра, на который ссылается переменная. Тип времени выполнения должен совпадать с типом времени компиляции или типом, производным от него или реализующим его. Назначение допустимо только в том случае, если неявное преобразование существует из типа времени выполнения в тип времени компиляции, например удостоверение, ссылка, бокс или числовое преобразование.
// Compile-time and run-time types match:
string message = "Hello, world!";
// Compile-time type differs from run-time type:
object boxed = "This is a string at run time";
IEnumerable<char> characters = "abcdefghijklmnopqrstuvwxyz";
В предыдущем примере boxed имеет тип object времени компиляции, но тип stringвремени выполнения. Задание работает, так как string является производным от object. Аналогичным образом characters имеет тип времени компиляции IEnumerable<char>, и присваивание выполняется, поскольку string реализует этот интерфейс. Тип времени компиляции управляет разрешением перегрузки и доступными преобразованиями. Тип времени выполнения управляет отправкой виртуальных методов, is выражениями и switch выражениями.
См. также
Спецификация языка C#
Дополнительные сведения см. в спецификации языка C#. Спецификация языка является авторитетным источником синтаксиса и использования языка C#.