Приведи примеры значимых типов данных
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Примеры значимых типов данных в C#
В C# значимые типы данных (value types) хранят свои значения непосредственно в памяти, где объявлена переменная, а не ссылку на объект в управляемой куче. Они располагаются в стеке (stack) или внутри других объектов. Ключевые особенности: копирование по значению, наследование от System.ValueType, невозможность иметь значение null (кроме Nullable<T>), высокая производительность для небольших данных.
1. Встроенные примитивные типы
Это базовые типы, определенные в системе типов C#.
-
Целочисленные типы:
byte(0 до 255),sbyte(-128 до 127)short(-32 768 до 32 767),ushort(0 до 65 535)int(-2 147 483 648 до 2 147 483 647),uint(0 до 4 294 967 295)long(-9.22×10¹⁸ до 9.22×10¹⁸),ulong(0 до 1.84×10¹⁹)
int age = 30; long population = 7_900_000_000; byte flags = 0b1010; // двоичный литерал -
Типы с плавающей точкой:
float(точность ~6-9 цифр, суффиксf)double(точность ~15-17 цифр, используется по умолчанию для дробных чисел)
float temperature = 36.6f; double pi = 3.141592653589793; -
Десятичный тип для финансовых расчетов:
decimal(высокая точность, 28-29 значащих цифр, суффиксm)
decimal price = 199.99m; decimal tax = price * 0.20m; // точный расчет без ошибок округления -
Логический тип:
bool(trueилиfalse)
bool isEnabled = true; bool hasPermission = false; -
Символьный тип:
char(один символ Unicode в UTF-16, одинарные кавычки)
char grade = 'A'; char newLine = '\n'; // escape-последовательность
2. Перечисления (enum)
Тип-перечисление определяет набор именованных константных значений.
enum DayOfWeek
{
Monday, // 0 по умолчанию
Tuesday, // 1
Wednesday, // 2
Thursday, // 3
Friday, // 4
Saturday, // 5
Sunday // 6
}
DayOfWeek today = DayOfWeek.Friday;
int dayNumber = (int)today; // 4
// С явными значениями
enum StatusCode : short
{
OK = 200,
NotFound = 404,
ServerError = 500
}
3. Пользовательские структуры (struct)
Структуры позволяют создавать составные значимые типы. Они могут содержать поля, свойства, методы, конструкторы.
public struct Point
{
public int X;
public int Y;
// Конструктор
public Point(int x, int y)
{
X = x;
Y = y;
}
public double DistanceToOrigin()
{
return Math.Sqrt(X * X + Y * Y);
}
}
// Использование
Point p1 = new Point(10, 20);
Point p2 = p1; // Копирование значений
p2.X = 30; // p1.X остается 10
// Readonly struct (C# 7.2+)
public readonly struct ImmutableVector
{
public readonly double X;
public readonly double Y;
public ImmutableVector(double x, double y) => (X, Y) = (x, y);
}
4. Nullable значимые типы
Специальная обертка Nullable<T> (синтаксический сахар T?) позволяет значимым типам принимать значение null.
int? nullableInt = null;
nullableInt = 42;
DateTime? birthDate = null;
if (birthDate.HasValue)
{
Console.WriteLine($"Birth date: {birthDate.Value}");
}
// Оператор объединения с null
int safeValue = nullableInt ?? -1; // -1 если null
5. Кортежи (tuple)
Значимые кортежи (System.ValueTuple) предоставляют легковесный способ группировки данных.
// Неименованный кортеж
var coordinates = (10, 20);
int x = coordinates.Item1;
// Именованный кортеж
var person = (Name: "Alice", Age: 25);
Console.WriteLine($"{person.Name} is {person.Age} years old");
// В качестве возвращаемого значения
static (int min, int max) GetMinMax(int[] numbers)
{
return (numbers.Min(), numbers.Max());
}
6. Ключевые отличия от ссылочных типов
Важно понимать разницу при работе с значимыми типами:
- Расположение в памяти: стек vs управляемая куча
- Копирование: полное копирование всех данных при присваивании
- Сравнение: по умолчанию побитовое сравнение (можно переопределить через
Equals) - Производительность: меньше нагрузки на GC, но копирование больших структур может быть дорогим
- Наследование: не могут наследовать от других типов (кроме интерфейсов)
7. Практический пример с отличиями
// Значимый тип
struct Vector2
{
public float X, Y;
}
// Ссылочный тип
class Vector2Class
{
public float X, Y;
}
Vector2 v1 = new Vector2 { X = 1, Y = 2 };
Vector2 v2 = v1; // Копирование значений
v2.X = 10; // v1.X остается 1
Vector2Class c1 = new Vector2Class { X = 1, Y = 2 };
Vector2Class c2 = c1; // Копирование ссылки
c2.X = 10; // c1.X тоже становится 10
Значимые типы оптимальны для небольших, неизменяемых или редко изменяемых данных, где важна производительность и предсказуемость размещения в памяти. Выбор между struct и class зависит от семантики данных: если объект представляет собой единое значение (координата, цвет, денежная сумма), обычно лучше использовать структуру.