初始化优先级 - const vs readonly vs static readonly

Dyl*_*dor 6 .net c#

例1

private const string _DefaultIconPath = _IconsPath + "default.ico";
private const string _IconsPath = "Icons/";
Run Code Online (Sandbox Code Playgroud)

这些字符串在运行时的值:

  • _DefaultIconPath:"Icons/default.ico"
  • _IconsPath:"图标/"

例2

private readonly string _DefaultIconPath = _IconsPath + "default.ico";
private readonly string _IconsPath = "Icons/";
Run Code Online (Sandbox Code Playgroud)

编译时间错误:

A field initializer cannot reference the non-static field, method, or property '_IconsPath'
Run Code Online (Sandbox Code Playgroud)

例3

private static readonly string _DefaultIconPath = _IconsPath + "default.ico";
private static readonly string _IconsPath = "Icons/";
Run Code Online (Sandbox Code Playgroud)

这些字符串在运行时的值:

  • _DefaultIconPath:"default.ico"(_IconsPath评估为null)
  • _IconsPath:"图标/"

为什么编译器在示例3中抛出编译错误,类似于示例2?

声明的顺序在static readonly字段定义的情况下很重要,但在const字段定义的情况下则不重要.

编辑:

我理解为什么字符串被初始化为那些特定的值.我不明白的是为什么示例2抛出编译错误,强制初始化发生在构造函数而不是变量声明中(这很有意义),但是示例3的行为方式并不相同.抛出相同的编译错误强制在静态构造函数中进行初始化是不是有意义?


另一个例子

private static string test = test2;
private static string test2 = test;
Run Code Online (Sandbox Code Playgroud)

这个例子说明了我想要解释的内容.编译器可以强制在静态构造函数中初始化静态(就像实例变量一样).为什么编译器允许它(或者为什么编译器不允许这个实例变量)?

Jus*_*les 0

有两个不相关的问题。

1. 编译错误

静态成员不需要类的实例来获取值。这就是为什么从静态成员引用静态成员不会引起问题。

初始化实例成员时,除非从构造函数中进行初始化,否则无法this在尝试初始化成员时进行引用。

由于您尚未将字段标记为Example 2as static,因此在引用这些成员之前,您必须首先实例化包含它们的任何对象的实例。

仅仅因为它们是,readonly并不意味着它们就是static。只读字段可以在其声明或类的构造函数中实例化,但它们不会在类的所有实例之间共享,也不能在没有正确实例化的情况下访问它们(假设它们没有像 那样显式地创建staticExample 3

2. 空值

原因_IconsPath为 nullExample 3是因为字段是按顺序声明和实例化的。颠倒顺序,您会发现它不再为空。