为了账号安全,请及时绑定邮箱和手机立即绑定

循环静态只读字段定义的奇怪行为

循环静态只读字段定义的奇怪行为

C#
ABOUTYOU 2022-07-23 16:45:17
在 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初始化。因此为空。在这种情况下,一旦静态构造完成,静态构造就会完成,因此具有值但包含空值。DefaultConstomersCustomerDefaultCustomersDefaultCustomers.NiceCustomerCustomer.UnwantedCustomers

这是一种定义明确的行为,可以用可预测的行为(如果没有帮助)来涵盖此类情况。

您的问题是您的两种类型之间的循环引用。将UnwantedCustomers其作为一个领域DefaultCustomers将避免该问题。


查看完整回答
反对 回复 2022-07-23
  • 1 回答
  • 0 关注
  • 87 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信