sealed в C#: зачем закрывать классыМодификатор
sealed существует в языке давно, но в современных версиях .NET он приобрёл дополнительный вес за счёт оптимизаций JIT-компилятора.Что делает
sealedsealed запрещает наследование. Если класс помечен как sealed, от него нельзя унаследоваться. Можно применять и к отдельным методам с override, тогда этот метод нельзя переопределить дальше по цепочке.public sealed class PaymentConfiguration
{
public string ApiKey { get; set; }
public int TimeoutInSeconds { get; set; }
}
// Ошибка компиляции: нельзя наследоваться от sealed-типа
public class GatewayX : PaymentConfiguration { }
Почему это влияет на производительность
Когда класс открыт для наследования, JIT не может знать наверняка, какой именно метод будет вызван в рантайме. Поэтому он генерирует косвенный вызов через
vtable.; Открытый класс — несколько обращений к памяти перед вызовом
mov eax, [edx]
mov eax, [eax+0x28]
call dword ptr [eax+0x10]
Для
sealed-класса JIT точно знает, какой метод будет вызван. Он убирает обращение к vtable, встраивает тело метода прямо в место вызова и оставляет минимум инструкций:; Sealed-класс — только проверка на null и возврат
cmp [edx], dl
ret
Дополнительно ускоряются операторы
is и as, потому что среде не нужно проходить по всему дереву наследования.Когда
sealed не подойдётEntity Framework создаёт прокси-классы в рантайме для ленивой загрузки. Если сущность
sealed, фреймворк не сможет её расширить:// EF не сможет создать прокси для sealed-класса
public class Order
{
public int Id { get; set; }
public virtual ICollection<OrderItem> Items { get; set; }
}
Аналогичная проблема с библиотеками для мокирования (Moq, NSubstitute). Они создают наследников в рантайме, и
sealed ломает это:public sealed class IntegrationService
{
public bool SendData(string data) => true;
}
// Moq выбросит исключение: нельзя наследоваться от sealed-типа
var mock = new Mock<IntegrationService>();
Архитекторы рекомендуют подход "sealed by default": закрывать все классы сразу, а наследование открывать только когда оно действительно нужно.
Это защищает дизайн от случайных расширений и даёт прирост производительности без дополнительных усилий.
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#il_люминатор