TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2352 2.63K
День 1944. #ЗаметкиНаПолях
Мысли о Первичных Конструкторах. Начало

См. также Введение в Первичные Конструкторы в C#12.

Лучшие варианты использования
Рассмотрим случаи, для которых первичные конструкторы хорошо подходят.

1. Базовая инициализация поля
Первичные конструкторы сокращают объём кода, который вам нужно написать, и вместо этого компилятор генерирует этот код за вас:
public class Person(string firstName, string lastName)
{
private readonly string _firstName = firstName;
private readonly string _lastName = lastName;
}

Однако, даже добавление валидации уже делает код не таким очевидным:
public class Person(string firstName, string lastName)
{
private readonly string _firstName =
!string.IsNullOrEmpty(firstName)
? firstName
: throw new ArgumentException(
"Must not be null or empty", nameof(firstName));
…
}

Вы не можете использовать защитные методы, доступные в .NET 7+:
ArgumentException.ThrowIfNullOrEmpty(firstName);

и уже одно это делает код стандартного конструктора более сжатым и понятным. Понятно, что можно создать методы-помощники и сократить количество кода, продолжая использовать первичные конструкторы, но зачем?

2. Инициализация в тестовом коде
Возьмем простой пример теста xunit для типа Person:
public class PersonTests(ITestOutputHelper output)
{
[Theory]
[InlineData("Jon", "")]
public void Person_throws_if_null_or_empty(
string firstName, string lastName)
{
output.WriteLine(
$"Testing '{firstName}' and '{lastName}'");
Assert.Throws<ArgumentException>(() =>
new Person(firstName, lastName));
}
}

Опустим тут ценность этого теста, и нужно ли нам использовать ITestOutputHelper в методе. Здесь интересно то, что добавление ITestOutputHelper в качестве параметра первичного конструктора упрощает тестовый класс. Для теста не имеет значения, хранится ли ITestOutputHelper в поле или нет, и является ли он изменяемым.

3. Внедрение зависимостей в контроллерах MVC
В ASP.NET Core, вы, вероятно, используете внедрение зависимостей и не часто проверяете зависимости, которые внедряются в контроллеры. Это делает их хорошими кандидатами для первичных конструкторов (можно даже использовать значения напрямую):
public class MyController(
ILogger<MyController> logger,
IService service) : ControllerBase
{
[HttpGet]
public ActionResult<Thing> Get()
{
logger.LogInformation("Get the thing");
return service.GetThing();
}
}

Очевидно, что это коротко и ясно. Но имейте в виду, что теперь зависимости изменяемы, и им можно назначать значения в теле контроллера, даже если вы, скорее всего, никогда не захотите этого делать.

Фактически, вы, вероятно, обнаружите, что большая часть ежедневного кода, который вы пишете в своём приложении, может использовать первичные конструкторы без какого-либо существенного влияния, кроме сокращения строк кода.

Тем не менее, при использовании первичных конструкторов есть вещи, на которые стоит обратить внимание.

Окончание следует…

Источник:
https://andrewlock.net/thoughts-about-primary-constructors-3-pros-and-5-cons/
  • 👍 12
More from @netdeveloperdiary
  1. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  2. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  3. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  4. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  5. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  6. Oct 3, 2026Post #3360
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 →