IConfiguration.Get возвращает значение свойства по умолчанию для IReadOnlyCollection

У меня было странное поведение при попытке получить коллекцию в конфигурации из appsettings.json с использованием .NET 6.

Мои занятия:

public record SomeOptions
{
    public IReadOnlyCollection<string> SomeColl { get; init; } = new List<string> { "wrongString" };
}

Мой appsettings.json:

{
  "Some": {
    "SomeColl": [ "expectedString" ]
  }
}

Затем я пытаюсь получить такие значения:

var section = configuration.GetSection("Some");
var options = section.Get<SomeOptions>();

Я получил значение по умолчанию из свойства (wrongString). Но если изменить свойство следующим образом:

public record SomeOptions
{
    public IReadOnlyCollection<string> SomeColl { get; init; } = null!;
}

Или

public record SomeOptions
{
    public ICollection<string> SomeColl { get; init; } = new List<string>();
}

Я получил значение от appsettings.json (expectedString). Может кто-нибудь объяснить, пожалуйста, почему это происходит?

Разве не было бы правильно public required IReadOnlyCollection<string> SomeColl { get; init; } вместо присвоения ему фиктивного значения?

Magnus 18.04.2024 11:31

@Magnus Магнус Это не так, потому что я хочу сделать его ненулевым. Но если у JSON пустая коллекция "SomeColl": [ ], она рассматривается как нулевая =(

VladOhotnikov 18.04.2024 15:34

Я не знал, что использование JsonSerializer может быть лучшей идеей, чем библиотека конфигурации.

Magnus 18.04.2024 17:12
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Эта часть исходного кода описывает следующее:

if (config.GetChildren().Any())
{
    // for arrays and read-only list-like interfaces, we concatenate on to what is already there, if we can
    if (type.IsArray || IsImmutableArrayCompatibleInterface(type))
    {
        if (!bindingPoint.IsReadOnly)
        {
            bindingPoint.SetValue(BindArray(type, (IEnumerable?)bindingPoint.Value, config, options));
        }

        // for getter-only collection properties that we can't add to, nothing more we can do
        return;
    }

для массивов и интерфейсов, подобных спискам только для чтения, мы объединяем то, что уже есть, если можем

Хотя мне не удалось найти документального подтверждения этого.

Вы можете попробовать сообщить об этом @github, но весьма вероятно, что это не будет воспринято как критическое изменение.

Я предполагаю, что это сделано для поддержки иерархических конфигураций (т. е. когда элементы массива определены в нескольких источниках конфигурации, хотя не уверен, что это тоже хорошая идея и иногда приводит к неожиданному поведению).

Спасибо! Забыл сказать - я использую .net 6. Итак, в ConfigurationBinder были внесены некоторые изменения. Но посмотрите, как в .net 6 логика работает аналогично - Если это тип только для чтения и уже инициализирован - верните инициализированный экземпляр, поскольку тип IS только для чтения

VladOhotnikov 18.04.2024 15:47

Другие вопросы по теме