在 Visual Studio 2017(调试版本)中运行以下代码时,我遇到了一些奇怪的行为:using System;using System.Collections.Generic;namespace ConsoleApp2{ public class Program { public static class DefaultCustomers { public static readonly Customer NiceCustomer = new Customer() { Name = "Mr. Nice Guy " }; public static readonly Customer EvilCustomer = new Customer() { Name = "Mr. Evil Guy " }; public static readonly Customer BrokeCustomer = new Customer() { Name = "Mr. Broke Guy" }; } public class Customer { public static readonly IEnumerable<Customer> UnwantedCustomers = new[] { DefaultCustomers.EvilCustomer, DefaultCustomers.BrokeCustomer }; public string Name { get; set; } public override string ToString() { return Name; } } public static void Main(string[] args) { Console.WriteLine(new Customer() { Name = "Some other customer" }); //Console.WriteLine(DefaultCustomers.NiceCustomer); foreach (var customer in Customer.UnwantedCustomers) { Console.WriteLine(customer != null ? customer.ToString() : "null"); } Console.ReadLine(); } }}控制台上的输出是Some other customerMr. Evil GuyMr. Broke Guy这大致是我预期的行为。但是,如果我取消注释 Program.Main(...) 中的第二行,输出将更改为Some other customerMr. Nice Guynullnull我知道可以通过将 UnwantedCustomers 转换为静态只读属性来轻松解决此问题。但我想知道所描述的行为是否遵循类和对象的初始化顺序,或者这种行为是否未定义?
1 回答
慕桂英3389331
TA贡献2036条经验 获得超8个赞
你有一个初始化问题的顺序。
static
字段(和属性)在静态构造函数运行之前初始化(或者如果你有的话会运行)。这是在对类的任何成员的任何引用被引用(静态或非静态)之前。
注释掉石灰后,当Customer.UnwantedCustomers
被引用时,它会触发静态构造,Customer
其前面是DefaultCustomers
.
但是更容易引用DefaultCustomers
它会触发DefaultCustomers
需要静态构造的静态构造Customer
。这意味着 的静态属性在 的静态属性之前Customer
初始化。因此为空。在这种情况下,一旦静态构造完成,静态构造就会完成,因此具有值但包含空值。DefaultConstomers
Customer
DefaultCustomers
DefaultCustomers.NiceCustomer
Customer.UnwantedCustomers
这是一种定义明确的行为,可以用可预测的行为(如果没有帮助)来涵盖此类情况。
您的问题是您的两种类型之间的循环引用。将UnwantedCustomers
其作为一个领域DefaultCustomers
将避免该问题。
- 1 回答
- 0 关注
- 87 浏览
添加回答
举报
0/150
提交
取消