В чем разница между статическим и нестатическим классом в C#?

Ответ

Нестатический (обычный) класс:

  • Может быть инстанциирован (создан его экземпляр) с помощью оператора new.
  • Может содержать как статические, так и нестатические (экземплярные) члены (поля, свойства, методы).
  • Может наследоваться от другого класса и быть унаследованным.
  • Может реализовывать интерфейсы.

Статический класс (объявляется с модификатором static):

  • Нельзя создать экземпляр. Он существует как единый набор функциональности.
  • Может содержать только статические члены.
  • Не может быть унаследован или наследовать от другого класса (компилятор неявно помечает его как sealed и abstract).
  • Не может реализовывать интерфейсы (поскольку интерфейсы определяют контракты для экземпляров).
  • Не может иметь конструкторов экземпляров, но может иметь статический конструктор для инициализации.

Когда использовать:

  • Статический класс: Идеален для утилитарных методов, которые не требуют состояния (например, Math, Path, Convert). Это способ организовать методы, логически связанные, но не требующие объекта.
  • Нестатический класс: Используется для моделирования сущностей, которые имеют состояние и поведение, и которых может быть множество экземпляров (например, User, Order, FileStream).

Пример:


// Статический класс - утилита
public static class StringHelper
{
    public static bool IsNullOrEmpty(string value) => string.IsNullOrEmpty(value);
}
// Использование: StringHelper.IsNullOrEmpty(text);

// Нестатический класс - сущность
public class Logger
{
    private string _logName;
    public Logger(string name) => _logName = name;
    public void Log(string message) => Console.WriteLine($"[{_logName}]: {message}");
}
// Использование: var logger = new Logger("App"); logger.Log("Start");

Ответ 18+ 🔞

А, ну вот, опять про эти статические классы спрашивают! Слушай, давай я тебе на пальцах объясню, а то в документации там такое нагорожено, что мозг вытекать начинает.

Представь себе, блядь, обычный класс — это как завод по производству табуреток. Ты пришёл, сказал: «Хочу табуретку!» — тебе её собрали, выдали. Хочешь десять — пожалуйста, наштампуем. У каждой табуретки своё состояние: одна покрашена, другая сломана, третья в жопу врезана. Это и есть нестатический класс. Ты его инстанциируешь через new, как будто заказ на заводе делаешь.

А теперь смотри сюда. Статический класс — это не завод, а, блядь, как универсальный набор отвёрток, который висит на стене в мастерской. Он один на всех. Ты не можешь сказать: «Дайте мне ещё один набор отвёрток Math». Он уже есть, ёпта! Весь его функционал — это статические методы, которые просто висят в пространстве имён, как инструменты на панели. Создать его экземпляр? Да хуй там! Компилятор тебе сразу: «Иди нахуй, мудак, это статический класс!»

И вот ещё что, запомни раз и навсегда: статический класс — это как монах, давший обет безбрачия. Он не может:

  • Наследоваться от кого-то или чтобы от него наследовались (он неявно sealed и abstract).
  • Реализовывать интерфейсы. Интерфейс — это контракт для экземпляров, а у статического класса экземпляров нет, он сам по себе хуй с горы.
  • Иметь нестатические поля, свойства или методы. Только статику! Конструктор экземпляра? Да ты что, охуел? Только статический конструктор для инициализации этой своей общей сранной кучи методов.

Когда что юзать? Всё просто, как три копейки:

  • Статический класс — для утилиток, которым похуй на состояние. Типа Path.Combine() или твоих хелперов, которые везде нужны. Это просто набор функций, сгруппированных под одним именем. Организация, блядь, чистота.
  • Нестатический класс — для всего, что должно жить своей жизнью, иметь состояние и которых может быть много. User, Order, Connection — вот это всё. У каждого экземпляра своя история, свои данные, свои косяки.

Смотри на примере, чтобы вообще всё стало ясно, как божий день:

// Статический класс — это как общая консоль в подъезде, которой все пользуются, но своей нет.
public static class StringHelper
{
    // Просто функция, которая висит в пространстве. Никакого состояния.
    public static bool IsNullOrEmpty(string value) => string.IsNullOrEmpty(value);
}
// Юзаешь так: StringHelper.IsNullOrEmpty(text); Без всяких `new`.

// А нестатический класс — это уже твой личный дневник с замком.
public class Logger
{
    private string _logName; // А вот это уже состояние! У каждого логгера своё имя.
    public Logger(string name) => _logName = name; // Конструктор есть!
    public void Log(string message) => Console.WriteLine($"[{_logName}]: {message}");
}
// А тут уже: var logger = new Logger("App"); logger.Log("Start");
// Можешь создать десять логгеров с разными именами — пожалуйста.

Короче, если тебе нужна просто пачка функций — делай статик. Если нужны живые, дышащие объекты с данными — обычный класс. Всё, вопрос закрыт, можно идти пить чай.