TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #926 1.36K
День семьсот пятьдесят первый.
В чём разница между DTO и POCO? Часть 1: DTO
Некоторые разработчики используют термины DTO и POCO как синонимы. Но правы ли они, и в чём разница между DTO и POCO?

DTO
Data Transfer Object - это объект, предназначенный для передачи данных. По определению DTO должен содержать только данные, без логики или поведения, т.е. не должен содержать методов. В C# DTO должен иметь только свойства, которые должны только получать и устанавливать данные, но не проверять их и не выполнять с ними других операций.

Что насчёт атрибутов и аннотаций данных?
Нет ничего необычного в добавлении метаданных в DTO, чтобы он поддерживал, например, проверку модели. Такие атрибуты не добавляют поведения самому DTO. Поведение находится вне объекта.

А как же модели представления, модели API и т.п.?
Термин DTO ничего не говорит о предполагаемом использовании объекта. Во многих архитектурах DTO могут выполнять несколько ролей. Например, в большинстве архитектур MVC с представлениями, которые поддерживают привязку к типу данных, DTO используются для передачи и привязки данных к представлению (модели представления). В идеале они не должны иметь никакого поведения, только данные, отформатированные так, как этого ожидает представление. Но не все модели представления являются DTO, поскольку в архитектурах MVVM модели обычно включают логику поведения. И даже в приложениях MVC иногда в модель представления добавляется логика, так что они больше не являются DTO.

По возможности называйте свои DTO в соответствии с их предполагаемым использованием. Имя FooDTO не указывает на то, как и где этот тип следует использовать в архитектуре приложения. Вместо этого отдавайте предпочтение именам, раскрывающим намерения, например FooViewModel.
Ниже приведен пример объекта DTO на C#:
public class ProductViewModel {
public int ProductId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal UnitPrice { get; set; }
}

Инкапсуляция и DTO
Инкапсуляция - важный принцип ООП, но он не относится к DTO. Поскольку DTO не имеют операций или поведения и не должны иметь скрытого состояния, они не нуждаются в инкапсуляции. Не усложняйте себе жизнь, используя закрытые мутаторы или пытаясь заставить ваши DTO вести себя как неизменяемые объекты. DTO должны быть простыми в создании, написании и чтении, и поддерживать сериализацию без дополнительных усилий.

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

Неизменяемость и записи
Неизменяемость имеет много преимуществ при разработке ПО, а также может быть полезной функцией в DTO. Неизменяемые DTO были головной болью разработчиков из-за невозможности использовать инициализаторы для свойств только для чтения и ограниченной поддержки сериализаторами. Однако это может измениться с появлением C# 9 и записей. Кстати, вы можете встретить ещё одну аббревиатуру - Data Transfer Record, (DTR). Вот один из способов определить DTR в C# 9 (позиционное объявление):
public record ProductDTO(int Id, string Name, string Description);
Кроме того, можно использовать init-свойства:
public record ProductDTO
{
public int Id { get; init; }
public string Name { get; init; }
}
Init-свойства поддерживают инициализацию при создании, а дальше доступны только для чтения, сохраняя неизменяемость записи. Также записи поддерживают сериализацию даже при позиционном объявлении. Вам может потребоваться несколько подсказок для сериализатора, если вы создадите свой собственный конструктор. Записи набирают популярность с выходом C# 9 и .NET 5, поэтому думаю, что они всё чаще будут использоваться для DTR.

Продолжение следует…

Источник:
https://ardalis.com/dto-or-poco/
More from @netdeveloperdiary
  1. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
  2. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  3. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  4. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  5. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  6. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
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 →