gpt4 book ai didi

c# - .NET 4.x 有重大变化 : Release mode does NOT execute static initializers properly if first call is to default ctor during deserialization

转载 作者:行者123 更新时间:2023-11-30 23:30:29 25 4
gpt4 key购买 nike

首先,我明白静态初始化器可以按不同的顺序调用...唯一的保证是它们将在首次使用该类的任何成员之前执行。

我的意思是,在 .NET 4.x 的 Release模式中,该保证被违反了。

在为类 X 自动生成反序列化代码期间,它调用类 X 的默认构造函数,并且在该代码中它正在访问一个尚未初始化的静态成员!

这在 .NET 3.5 中从未发生过;在 .NET 4.x 的 Debug模式下它永远不会发生(至少现在还没有)。但在 .NET 4.x 的 Release模式下,它的发生相当一致。

问题:

(1) 是否有编译器标志或设置可以关闭 .NET 4.x 添加的更延迟地评估静态初始值设定项的优化?

(2) 有没有办法设置 Debug模式来进行所有优化(除了静态初始化优化)?

(3) 是否有一些我们可以放入类中的#pragma 或指令,以使其初始化程序不那么懒惰地运行?

(4) 我看到有人提到静态构造函数可能会影响静态初始化器的惰性求值,但不清楚它们是否过度依赖静态初始化器顺序。有谁知道使用静态初始化程序遍历每个类并添加静态承包商是否可以解决这个问题?

(5) 关于如何解决这个问题还有其他建议吗? (回到 .NET 3.5 是非常不可取的,因为我们需要移动到 64b,我们不想失去编辑和继续。)

最佳答案

感谢您在上面的评论,@dbc;在点击这些链接后,我终于意识到了关键问题:

我对上述保证的陈述是错误的...静态初始化程序不保证在首次使用该类的任何成员之前执行...相反,它们保证在首次使用之前执行该类的任何 STATIC 成员。因此,当反序列化代码调用构造函数来实例化类的实例时,不能保证触发静态初始化程序。

静态构造函数的规则是不同的......它保证在第一次使用任何构造函数(该类的任何对象的第一次实例化)之前执行。因为它是静态的,所以它会触发所有静态初始化程序运行。

所以,这确实是解决方案:为每个类添加一个静态构造函数,该类具有需要在使用该类之前运行的静态初始化程序。 (我曾阅读过有关使用静态构造函数的先前建议,但他们从未明确表示静态初始化程序仅通过访问 STATIC 成员触发,这与静态构造函数不同。)

(基于 10 多年的 .NET 编码,我非常确定 2.0 到 3.5 的实现是这样的,静态初始化器将通过实例化类的实例来触发。所以,我仍然断言它是一个重大变化; 但语言规范不会争辩说我在过去 10 年里有错误的代码,幸运的是它能工作。)

关于c# - .NET 4.x 有重大变化 : Release mode does NOT execute static initializers properly if first call is to default ctor during deserialization,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34972838/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com