#c# #asp.net-core #.net-core #c#-9.0
#c# #asp.net-core #.net-ядро #c #-9.0
Вопрос:
Я заметил, что новые init
свойства в C # версии 9, похоже, привязываются при использовании в строго типизированных классах опций (шаблон опций).
Другими словами, это работает:
class SomeSettings
{
public string FirstSetting { get; init; }
public bool SecondSetting { get; init; }
}
...
configuration.GetSection(nameof(SomeSettings)).Get<SomeSettings>();
Но есть ли какие-либо потенциальные «подводные камни» или ограничения, о которых мы должны знать?(При использовании либо с прямой привязкой, либо при вводе, как IOptions<>
с Configure()
.)
По общему признанию, моя мотивация заключается в том, что я думаю о привязке и регистрации этих экземпляров непосредственно во время настройки как одиночных, без надоедливой IOptions<>
оболочки. Единственной причиной, по которой я до сих пор не сделал, была изменчивость свойств, но init
, похоже, это решает.
Комментарии:
1. Я не думаю, что это может сработать, поскольку конфигурация может поступать из нескольких источников…
Ответ №1:
init
понижается до set
свойства в IL. Это было сделано намеренно, чтобы отражение, которое задает свойства, продолжало работать, так что init
это безопасно, да.
Подробнее см. Обсуждение этого вопроса, начинающееся здесь, и, в частности, этот комментарий:
Я думаю, что это вопрос соотношения затрат и выгод.
Это действительно компромисс между затратами и выгодами, и после обсуждения мы решили отдать предпочтение инициализации, работающей в существующих сценариях, а не стоимости изменения каждого отдельного из этих сценариев для поддержки свойств инициализации.
Какой самый популярный пакет nuget, который вы можете найти, на который это негативно повлияет, потому что они установят что-то, чего не должны?
Здесь следует рассмотреть еще один аспект: как далеко вы хотите зайти в принудительном исполнении? Здесь следует иметь в виду, что среда выполнения обеспечивает нулевое принудительное исполнение полей экземпляра только для чтения. Это означает, что отражение, даже публичное отражение, сегодня может быть доступно только для чтения, и за это нет штрафа.
Один из аспектов, который мы рассматривали в LDM при обсуждении пакетов такого типа, заключается в следующем: «какова ценность использования средств инициализации в соответствии с более высоким стандартом, чем поля только для чтения? Ответ, к которому мы пришли, заключается в том, что в этом нет особой ценности.
Отражение уже может сделать недействительной неизменность объекта, и это чрезвычайно трудно изменить. Следовательно, делая init доступным для отражения, мы не меняем здесь семантику, мы просто приспосабливаемся к существующей системе. В этом смысле компромисс здесь очень разумный с нашей точки зрения.
Комментарии:
1. Спасибо. Кажется, это окончательно отвечает на вопрос (т. Е. Привязка к ‘init’ безопасна), поэтому я принимаю ответ.