Безопасны ли свойства инициализации C # 9 для привязки конфигурации (IOptions)?

#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’ безопасна), поэтому я принимаю ответ.