C# 9“init”属性可安全用于配置绑定(IOptions)吗?

MrV*_*ype 5 c# .net-core asp.net-core c#-9.0

我注意到新的initC# 版本 9 中的新属性在强类型选项类(选项模式)中使用时似乎是绑定的。

换句话说,这有效:

    class SomeSettings
    {
        public string FirstSetting { get; init; }
        public bool SecondSetting { get; init; }
    }

    ...

    configuration.GetSection(nameof(SomeSettings)).Get<SomeSettings>();
Run Code Online (Sandbox Code Playgroud)

但我们是否应该注意任何潜在的“陷阱”或限制?(当与直接绑定一起使用时,或IOptions<>Configure()注入时。)

诚然,我的动机是我正在考虑在配置时直接将这些实例绑定和注册为单例,而不需要讨厌的IOptions<>包装器。到目前为止我还没有这样做的唯一原因是属性的可变性,但init似乎解决了这个问题。

Yai*_*adt 7

init降低到set伊利诺伊州的房产。这是故意的,这样设置属性的反射将继续工作,init所以这是安全的。

有关更多信息,请参阅从此处开始的讨论,特别是评论:

我认为这是一个成本与效益的问题。

这确实是一种成本效益权衡,经过讨论,我们决定支持 init 在现有场景中工作,而不是改变这些场景中的每一个以支持 init 属性。

您可以找到的最流行的 nuget 软件包是什么,这会产生不利影响,因为它们会设置不应该设置的内容?

这里要考虑的另一个方面是你想在执法方面走多远?这里要记住的一点是运行时提供只读实例字段的零强制。这意味着反思,甚至是公开反思,今天可以只读地践踏一切,而且这样做不会受到惩罚。

在讨论这些类型的包时,我们在 LDM 中考虑的一个方面是“将 init 访问器保持为比只读字段更高的标准有什么价值?我们得出的答案是这样做没有太多价值。

反射已经可以使对象的不变性失效,并且这种情况极不可能改变。因此,通过使 init 可被反射访问,我们并没有改变这里的语义,我们只是适应现有的系统。从这个意义上说,从我们的角度来看,这里的权衡是非常合理的。