C#-当自动属性给定默认值时与访问器的行为差异

C#-当自动属性给定默认值时与访问器的行为差异,c#,C#,我试图理解为什么初始化顺序会改变这里的值。属性的访问器不应该将指定的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

我试图理解为什么初始化顺序会改变这里的值。属性的访问器不应该将指定的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

印刷品

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); }


无论指定的顺序如何,我都会得到一致的值

这有两个部分

首先,.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);
    }
}

静态初始化器按照代码中给定的顺序执行,只执行一次,因此第一个代码块将
EndDate
属性视为
DateTime
的默认值(即
1/1/0001 12:00:00 AM

最后一个代码块没有初始值设定项,它实际上是一个完整方法的简写,每次调用属性时都执行。例如:

private static DateTime StartDate
{
    get
    {
        return new DateTime(EndDate.Year, 1, 1); 
    }
}

第二个和第三个看起来相同,2是预期输出。如果我使用3,无论顺序如何,我都会得到预期的输出。问题是1。抱歉,该链接似乎没有任何与上述查询相关的内容。我错过什么了吗?
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);
    }
}
private static DateTime StartDate
{
    get
    {
        return new DateTime(EndDate.Year, 1, 1); 
    }
}