在 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 關注
- 111 瀏覽
添加回答
舉報
0/150
提交
取消