Гид по технологиям

Классы в C#: как создавать, использовать и проектировать

6 min read Программирование Обновлено 01 Apr 2026
Классы в C#: создание и примеры
Классы в C#: создание и примеры

Человек работает за ноутбуком

Классы — базовый способ моделировать данные и поведение в C#. В статье показано, как объявлять классы, поля, свойства, конструкторы, методы и создавать объекты. Также описаны альтернативы, лучшие практики, контрольные списки и критерии приёмки.

Введение

Объектно-ориентированное программирование позволяет думать о программе в терминах реальных объектов: у них есть состояние (поля/свойства) и поведение (методы). В C# класс — это ссылка на тип (reference type). Пока вы не создадите экземпляр класса через оператор new, переменная такого типа может содержать null.

Ниже — подробное руководство с примерами и полезными практиками для безопасной и ясной работы с классами в C#.

Объявление класса

Чтобы объявить класс в C#, нужны несколько компонентов:

  • модификатор доступа;
  • ключевое слово class;
  • имя класса;
  • пара фигурных скобок, внутри которых находятся поля, конструкторы и методы.

Пример минимального объявления:

internal class Customer { }

Этот класс доступен другим типам внутри той же сборки (assembly). В C# есть шесть модификаторов доступа:

  • public — доступен всем.
  • private — доступен только внутри того же типа.
  • protected — доступен наследникам.
  • internal — доступен внутри той же сборки.
  • protected internal — доступен в той же сборке или в классах-наследниках из других сборок.
  • private protected — доступен наследникам только в той же сборке.

Важно: используйте наименьший требуемый уровень доступа по принципу наименьших привилегий.

Поля, свойства и доступ к данным

Поля (fields) содержат состояние объекта. Обычно поля делают приватными, а доступ к ним организуют через свойства (properties) или методы доступа (геттеры/сеттеры).

Пример с явными геттерами и сеттерами:

internal class Customer
{
    // поля
    private int IdNumber;
    private string Name;
    private double Total;

    // сеттеры
    public void SetIdNumber(int IdNumber) { this.IdNumber = IdNumber; }
    public void SetName(string Name) { this.Name = Name; }
    public void SetTotal(double Total) { this.Total = Total; }

    // геттеры
    public int GetIdNumber() { return this.IdNumber; }
    public string GetName() { return this.Name; }
    public double GetTotal() { return this.Total; }
}

В современных версиях C# предпочтительнее использовать свойства — компактную форму, совмещающую хранение и доступ:

internal class Customer
{
    public int IdNumber { get; set; }
    public string Name { get; set; }
    public double Total { get; set; }
}

Свойства позволяют позже подключить логику в get/set, не меняя внешний интерфейс класса.

Советы по оформлению полей и свойств:

  • Приватные поля именуйте в camelCase или с префиксом _ (например, _idNumber).
  • Публичные свойства используйте в PascalCase (IdNumber, Name).
  • Для неизменяемых данных используйте readonly-поля или init-only свойства.
  • При работе с nullable-типами явно включайте аннотации nullability и проверяйте входные параметры.

Конструкторы

Конструктор — метод, который вызывается при создании экземпляра класса. Он имеет то же имя, что и класс и не возвращает значение.

Типы конструкторов:

  • дефолтный (без параметров) — инициализирует поля значениями по умолчанию;
  • параметризованный (первичный) — принимает параметры для установки состояния;
  • конструктор копирования — создаёт новый экземпляр на основе существующего.

Дефолтный конструктор

// дефолтный конструктор
public Customer()
{
    IdNumber = 0;
    Name = "unknown";
    Total = 0;
}

Параметризованный конструктор

Избегайте параметров, не относящихся к полям. Пример согласованного конструктора:

// параметризованный конструктор
public Customer(int IdNumber, string Name, double Total)
{
    this.IdNumber = IdNumber;
    this.Name = Name;
    this.Total = Total;
}

Конструктор копирования

// конструктор копирования
public Customer(Customer previousCustomer)
{
    this.IdNumber = previousCustomer.IdNumber;
    this.Name = previousCustomer.Name;
    this.Total = previousCustomer.Total;
}

Конструктор копирования копирует примитивные значения и ссылки. Для глубокого копирования вложенных объектов нужен явный код копирования.

Методы

Метод — это поведение класса. У метода есть модификатор доступа, возвращаемый тип, имя и тело.

// метод
public string CustomerDetail()
{
    return "ID: " + IdNumber + " Name: " + Name + " Total: " + Total;
}

Это простой пример, возвращающий строковое представление состояния объекта. Для форматирования данных предпочтительнее использовать интерполяцию строк (C#):

public string CustomerDetail()
{
    return $"ID: {IdNumber} Name: {Name} Total: {Total}";
}

Создание объектов и использование

Создадим объект с дефолтным конструктором:

Customer John = new Customer();
Console.WriteLine(John.Name);

Ожидаемый вывод:

unknown

Создание объекта с параметризованным конструктором:

Customer John = new Customer(1001, "John Doe", 250.20);
Console.WriteLine(John.CustomerDetail());

Ожидаемый вывод:

ID: 1001 Name: John Doe Total: 250.2

Копирование объекта:

Customer Johnny = new Customer(John);
Console.WriteLine(Johnny.CustomerDetail());

Вывод:

ID: 1001 Name: John Doe Total: 250.2

Если выполнить копирование дефолтного объекта, у копии будут те же значения полей, но это разные ссылки:

Customer John = new Customer();
Customer Johnny = new Customer(John);
Console.WriteLine(Johnny.CustomerDetail());

Вывод:

ID: 0 Name: unknown Total: 0

Альтернативы классам

Иногда класс — не лучший выбор. Рассмотрите альтернативы:

  • struct — value type, полезен для небольших типов, где важна копия значения, а не ссылка. Не используйте struct для больших или мутируемых объектов.
  • record — удобен для неизменяемых объектов и поддержки семантики “значения” (value-based equality). Records имеют компактный синтаксис и встроенные методы копирования.
  • tuple / anonymous types — для временных групп значений без явного типа.

Пример записи record:

public record CustomerRecord(int IdNumber, string Name, double Total);

Records хороши, когда важна семантика неизменяемости и сравнения по значениям.

Когда классы не подходят

  • Нужны небольшие, часто копируемые структуры — используйте struct.
  • Вам нужна неизменяемая модель данных со встроенным копированием и сравнению по значениям — record предпочтительнее.
  • Низкоуровневое управление памятью или производительность в hot path — стоит проводить профилирование и рассматривать value types.

Лучшие практики проектирования классов

  • Делайте поля private, предоставляйте публичные свойства.
  • Используйте PascalCase для публичных членов и camelCase/_camel для приватных.
  • Поддерживайте инварианты в конструкторах: объекты должны быть корректными после создания.
  • Предпочитайте небольшие классы с одной ответственностью (Single Responsibility Principle).
  • Документируйте публичный API класса комментариями XML.
  • Используйте nullability и проверяйте входные параметры.
  • Для потокобезопасности делайте объекты неизменяемыми, если возможно.

Important: помните про управление null и проверку границ входных данных в сеттерах и конструкторах.

Паттерны и подходы

  • Фабричные методы (Factory) — инкапсулируют сложную логику создания объектов.
  • Билдер (Builder) — полезен, когда у класса много параметров.
  • DTO — отдельные классы для передачи данных без бизнес-логики.

Пример фабрики:

public static class CustomerFactory
{
    public static Customer CreateVip(int id, string name) => new Customer(id, name, 10000);
}

Ментальные модели и эвристики

  • Класс = шаблон; объект = экземпляр шаблона.
  • Поле = состояние; метод = поведение.
  • Свойства служат адаптером между внутренним состоянием и внешним интерфейсом.
  • Используйте “минимальный публичный интерфейс”: открывайте только то, что требуется.

Решающее дерево: класс, struct или record

flowchart TD
  A[Нужен тип данных?] --> B{Будет ли он неизменяемым?}
  B -- Да --> C{Нужна ли семантика сравнения по значению?}
  B -- Нет --> D{Небольшой ли он и часто копируется?}
  C -- Да --> E[Используйте record]
  C -- Нет --> F[Используйте class]
  D -- Да --> G[Используйте struct]
  D -- Нет --> F

Контрольные списки по ролям

Разработчик:

  • Поля приватные, свойства публичные.
  • Проверки входных параметров в конструкторах.
  • Тесты на создание экземпляров и методы.

Архитектор:

  • Выбран правильный тип (class/struct/record).
  • Слои отделены (DTO vs Domain).
  • Миграция/совместимость учтена для публичных API.

Тестировщик:

  • Тесты на конструкторы: дефолтный, параметризованный, копирование.
  • Тесты на сериализацию/десериализацию, если применимо.

Критерии приёмки

  • Экземпляр создаётся без исключений для допустимых входных данных.
  • Значения свойств устанавливаются и возвращаются корректно.
  • Метод CustomerDetail возвращает ожидаемую строку.
  • Копирование через конструктор создаёт отдельный объект со скопированными значениями.

Факты и полезные числа

  • Модификаторов доступа в C# — 6.
  • Класс — reference type; struct — value type.
  • Record поддерживает удобное копирование и сравнение по значениям.

Безопасность и приватность

  • Не храните чувствительные данные в публичных свойствах без шифрования.
  • Для секретов используйте безопасные хранилища и короткоживущие объекты.
  • Учитывайте сериализацию: при сериализации класс может раскрыть внутренние поля.

Краткая методология разработки класса

  1. Определите ответственность класса и его публичный контракт.
  2. Выберите подходящий тип (class/struct/record).
  3. Спроектируйте поля и свойства, обеспечьте инварианты в конструкторе.
  4. Добавьте методы только для поведения, относящегося к состоянию.
  5. Напишите модульные тесты и документацию.

Глоссарий (в одну строку)

  • Класс — шаблон для создания объектов.
  • Объект — экземпляр класса, содержащий состояние и поведение.
  • Свойство — интерфейс доступа к полю с возможностью логики доступа.
  • Конструктор — метод для инициализации нового экземпляра.
  • Метод — операция, выполняющая поведение объекта.
  • Экземпляр — конкретный объект в памяти.

Итог

Классы в C# — гибкий инструмент для моделирования сущностей и поведения. Используйте свойства, контролируйте доступ, поддерживайте инварианты в конструкторах и выбирайте тип (class/struct/record) в соответствии с требованиями производительности, семантики сравнения и неизменяемости.

Заметки

  • Примеры кода показаны для пояснения; адаптируйте их под конкретную версию C# и стиль проекта.

Summary

  • Классы моделируют состояние и поведение в C#.
  • Свойства упрощают доступ к полям.
  • Конструкторы и паттерны проектирования помогают поддерживать корректность объектов.
  • Рассматривайте struct и record как альтернативы в соответствующих сценариях.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как удалить видео в TikTok
Социальные сети

Как удалить видео в TikTok

Как найти и работать с фантомным писателем
Авторство

Как найти и работать с фантомным писателем

FreeFileSync: синхронизация локальных резервных копий
Резервное копирование

FreeFileSync: синхронизация локальных резервных копий

Как делать скриншоты на Android TV
Android TV

Как делать скриншоты на Android TV

Как сделать прозрачные окна в Windows 10
Windows

Как сделать прозрачные окна в Windows 10

Эмодзи‑реакции в WhatsApp: как использовать
Мессенджеры

Эмодзи‑реакции в WhatsApp: как использовать