← Назад к вопросам

Какие знаешь ссылочные типы данных в С#?

1.0 Junior🔥 243 комментариев
#Основы C# и .NET

Комментарии (3)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Ссылочные типы данных в C#

В C# все типы данных делятся на значимые (value types) и ссылочные (reference types). Ключевое отличие ссылочных типов заключается в том, что они хранятся в управляемой куче (managed heap), а переменные содержат не сами данные, а ссылку (адрес в памяти) на эти данные.

Основные ссылочные типы в C#

1. Классы (class)

Наиболее распространенный ссылочный тип. Все классы, включая пользовательские, являются ссылочными типами.

// Пример класса - ссылочного типа
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// Использование
Person person1 = new Person { Name = "Иван", Age = 30 };
Person person2 = person1; // Копируется ссылка, а не объект
person2.Name = "Петр"; // Изменяется общий объект
Console.WriteLine(person1.Name); // Выведет "Петр"

2. Интерфейсы (interface)

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

public interface ILogger
{
    void Log(string message);
}

public class FileLogger : ILogger
{
    public void Log(string message) => Console.WriteLine($"File: {message}");
}

// Использование интерфейсной ссылки
ILogger logger = new FileLogger(); // Ссылка на объект через интерфейс

3. Делегаты (delegate)

Ссылочный тип, представляющий ссылку на метод с определенной сигнатурой.

public delegate void MessageHandler(string message);

public class Notifier
{
    public void SendEmail(string msg) => Console.WriteLine($"Email: {msg}");
}

// Использование делегата
Notifier notifier = new Notifier();
MessageHandler handler = notifier.SendEmail; // Ссылка на метод
handler("Привет!"); // Вызов метода через делегат

4. Массивы (array)

Все массивы в C# являются ссылочными типами, независимо от типа элементов.

// Массив значимых типов (int) - все равно ссылочный тип
int[] numbers = new int[5] { 1, 2, 3, 4, 5 };
int[] copy = numbers; // Копируется ссылка
copy[0] = 100;
Console.WriteLine(numbers[0]); // Выведет 100

5. Строки (string)

Особый ссылочный тип, который обладает иммутабельностью (неизменяемостью). Несмотря на то, что string является классом, он ведет себя несколько иначе из-за неизменяемости.

string str1 = "Hello";
string str2 = str1; // Копируется ссылка
str2 = "World"; // Создается новый объект в куче
Console.WriteLine(str1); // Остается "Hello"

6. object (System.Object)

Базовый тип для всех типов в .NET. Все типы наследуются от object, поэтому любой объект может быть присвоен переменной типа object через упаковку (boxing).

int value = 42; // value type
object obj = value; // boxing - создается ссылочный тип в куче
int unboxed = (int)obj; // unboxing

7. Динамический тип (dynamic)

Введен в C# 4.0, позволяет обходить проверку типов во время компиляции.

dynamic dynamicVar = "Это строка";
Console.WriteLine(dynamicVar.Length); // Работает
dynamicVar = 10; // Теперь хранит int
dynamicVar = dynamicVar + 5; // Работает

8. Записи (record)

Начиная с C# 9.0, record является ссылочным типом с автоматической реализацией value-based равенства.

public record Point(int X, int Y);

Point p1 = new Point(1, 2);
Point p2 = p1 with { X = 3 }; // Создает новую ссылку с измененными данными

Ключевые особенности ссылочных типов:

  • Хранение в куче: Объекты размещаются в управляемой куче
  • Сборка мусора: Управление памятью осуществляется через Garbage Collector
  • Ссылочная семантика: При присваивании копируется ссылка, а не данные
  • Возможность наследования: Поддерживают наследование и полиморфизм
  • Значение null: Могут иметь значение null (отсутствие ссылки)

Пример, демонстрирующий различие с значимыми типами:

// Значимый тип
struct ValuePoint { public int X, Y; }

// Ссылочный тип
class ReferencePoint { public int X, Y; }

ValuePoint vp1 = new ValuePoint { X = 1, Y = 2 };
ValuePoint vp2 = vp1; // Копируются данные
vp2.X = 100; // vp1.X остается 1

ReferencePoint rp1 = new ReferencePoint { X = 1, Y = 2 };
ReferencePoint rp2 = rp1; // Копируется ссылка
rp2.X = 100; // rp1.X также становится 100

Понимание различий между ссылочными и значимыми типами критически важно для эффективного управления памятью, производительности и предотвращения ошибок в C# приложениях.