我试图理解为什么初始化顺序会在此处更改值。属性的访问者不应该返回默认的I / O指定的值。 谢谢。
void Main()
{
Console.WriteLine(StartDate);
Console.WriteLine(EndDate);
}
private static DateTime StartDate { get; } = new DateTime(EndDate.Year, 1, 1);
private static DateTime EndDate { get; } = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddDays(-1);
此打印
1/1/0001 12:00:00 AM
31/12/2018 12:00:00 AM
而
void Main()
{
Console.WriteLine(StartDate);
Console.WriteLine(EndDate);
}
private static DateTime EndDate { get; } = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddDays(-1);
private static DateTime StartDate { get; } = new DateTime(EndDate.Year, 1, 1);
打印
1/1/2018 12:00:00 AM
31/12/2018 12:00:00 AM
如果我将属性更改为
private static DateTime EndDate { get => new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddDays(-1); }
private static DateTime StartDate { get => new DateTime(EndDate.Year, 1, 1); }
或
private static DateTime StartDate => new DateTime(EndDate.Year, 1, 1);
private static DateTime EndDate => new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddDays(-1);
我得到一致的值,而不管它们指定的顺序如何。
答案 0 :(得分:2)
这有两部分。
首先,.NET将第一个示例转换为静态构造函数,并按照声明的顺序初始化每个变量。
第二,.NET中的所有类字段在运行代码之前都初始化为其默认值。
因此,当您使用EndDate
时,它已设置为其默认值,但尚未运行它的初始化程序。您正在访问其默认值。本质上,您正在生成以下代码:
class App
{
static readonly DateTime _startDate, _endDate;
static DateTime StartDate => _startDate;
static DateTime EndDate => _endDate;
static App()
{
// this code is put here implicitly by .NET
_startDate = default;
_endDate = default;
// and this code is put here by C#,
// translated from your initializers,
// in the order they were declared.
_startDate = new DateTime(_endDate.Year, 1, 1);
_endDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddDays(-1);
}
}
答案 1 :(得分:0)
静态初始化程序按照它们在代码中给出的顺序执行,并且仅执行一次,因此为什么第一个代码块将EndDate
属性视为{{1 }}(即DateTime
)。
最后一个代码块没有初始化程序,它是expression-bodied member,实际上是一个完整的方法的简写形式,该方法在您每次调用属性时都会执行。例如:
1/1/0001 12:00:00 AM