TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2082 1.88K
День 1715. #ЗаметкиНаПолях
Виды Структур в C#. Начало
Рассмотрим, в чём разница между структурой, структурой для чтения и ref-структурой, а также, какие ограничения есть у этих типов.

1. Структура
Все в той или иной степени ими пользовались. Структура — это тип значения, который в идеале должен представлять одно логическое значение: DateTime, int, double или TimeSpan, либо пользовательские, вроде Point2D, которая может состоять из координат x и y. В документации Microsoft есть подсказка, когда не следует использовать структуры: если экземпляр придётся часто упаковывать.

Обычно типы значений, такие как структура, находятся в стеке. Стек — это хороший способ моделирования времени жизни переменной. Если вы объявите int в функции, он будет жить только в этой области:
public void MyFunc()
{
int a = 2;
}
Здесь a существует только внутри MyFunc, и только на стеке. Но если мы используем какой-либо тип значения, например, в качестве поля в классе, тогда эта переменная должна находиться в куче, поскольку её родитель находится в куче.

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

Пример структуры:
public struct Color
{
public byte Red;
public byte Green;
public byte Blue;

public Color() {
Red = 0; Green = 0; Blue = 0;
}

public void ShiftToGrayscale()
{
var avg = (byte)((Red + Green + Blue) / 3);
Red = Green = Blue = avg;
}
}

2. Структура только для чтения
readonly struct были представлены в C# 7.2. Основная идея состоит в том, чтобы сделать структуру неизменяемой. Конечно, вы можете сделать это без модификатора только для чтения (например, DateTime существует с самого начала), но компилятор поможет вам, если вы нарушите логику только для чтения.

Пример выше выдаст несколько ошибок компилятора, если добавить readonly к объявлению структуры. Причина проста: во-первых, мы должны объявить все поля как readonly (иначе любой вызывающий объект мог бы просто изменить их). Во-вторых, метод ShiftToGrayscale по-прежнему изменяет внутреннее состояние, поэтому его тоже надо изменить на выдачу новой структуры:
public readonly struct Color
{
public readonly byte Red;
public readonly byte Green;
public readonly byte Blue;

public Color() {
Red = 0; Green = 0; Blue = 0;
}

public Color(byte red, byte green, byte blue)
{
Red = red; Green = green; Blue = blue;
}

public Color ShiftToGrayscale()
{
var avg = (byte)((Red + Green + Blue) / 3);
return new Color (avg, avg, avg);
}
}

Неизменяемость дает много преимуществ:
- Повышенная тестируемость
- Потокобезопасность.
- Атомарность неудачи.
- Отсутствие скрытых побочных эффектов.

Компилятор попытается помочь вам с неизменяемостью, но не сможет её гарантировать. Если в структуре есть список, его члены всё равно можно будет изменять:
public readonly struct MyStruct
{
public readonly List<int> myStuff
= new List<int>() { 1, 2 };

public MyStruct() {}

public void Mutate()
{
myStuff[0] = 3;
}
}

Окончание следует…

Источник:
https://steven-giesel.com/blogPost/2a52cd8d-b3b2-42e4-87e8-d6dc14147ddb
  • 👍 23
More from @netdeveloperdiary
  1. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  2. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  3. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  4. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  5. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  6. Oct 3, 2026Post #3360
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →