6

示例 1

private const string _DefaultIconPath = _IconsPath + "default.ico";
private const string _IconsPath = "Icons/";

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

  • _DefaultIconPath:“图标/default.ico”
  • _IconsPath: "图标/"

示例 2

private readonly string _DefaultIconPath = _IconsPath + "default.ico";
private readonly string _IconsPath = "Icons/";

编译时错误:

A field initializer cannot reference the non-static field, method, or property '_IconsPath'

示例 3

private static readonly string _DefaultIconPath = _IconsPath + "default.ico";
private static readonly string _IconsPath = "Icons/";

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

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

问题

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

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

编辑:

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


另一个例子

private static string test = test2;
private static string test2 = test;

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

4

3 回答 3

0

示例 3 使用static变量,因此是允许的。

示例 2 失败,因为 C# 不允许变量初始化程序引用正在创建的实例。请参阅 Jon Skeet在此处的解释。

你可以这样做:

public class YourClass {
  private readonly string _IconsPath;
  private readonly string _DefaultIconsPath;

  public YourClass() {
    _IconsPath = "Icons/";
    _DefaultIconPath = _IconsPath + "default.ico";
  }
}
于 2012-08-09T19:38:28.320 回答
0

在示例 2 中,“_IconsPath”未初始化,无法使用。

在示例 3 中,您正在访问一个静态字段(如您所知)。MSDN 说的很好A static method, field, property, or event is callable on a class even when no instance of the class has been created.

这里

更新:示例 3:与以下内容相同:

private static readonly string _DefaultIconPath = MyStaticClass._IconsPath + "default.ico";
private static readonly string _IconsPath = "Icons/";

关键是您没有使用字段(亲爱的未初始化,您正在使用(“其他”/“新”)静态类(在以静态方式使用它之前不必创建它) .

于 2012-08-09T20:01:00.090 回答
0

有两个不相关的问题。

1.编译错误

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

this初始化实例成员时,尝试初始化成员时不能引用,除非您从构造函数中这样做。

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

仅仅因为他们是readonly并不意味着他们是static。只读字段可以在它们的声明或类的构造函数中实例化,但它们不会在类的所有实例之间共享,也不能在没有适当实例化的情况下访问(假设它们没有显式地制作为staticlike Example 3)。

2.空值

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

于 2012-08-09T19:34:15.650 回答