【问题标题】:Does the order of readonly variable declarations guarantee the order in which the values are set?只读变量声明的顺序是否保证设置值的顺序?
【发布时间】:2026-01-29 18:25:01
【问题描述】:

假设我要为文件路径设置一些只读变量,我能否保证根据声明顺序分配值的顺序?

例如

static readonly string basepath = @"my\base\directory\location";
static readonly string subpath1 = Path.Combine(basepath, @"abc\def");
static readonly string subpath2 = Path.Combine(basepath, @"ghi\klm";

这是一种安全的方法,还是basepathsubpath1subpath2 引用该字符串时可能仍是该字符串的默认值?

我意识到我可以通过在构造函数中而不是在声明时分配值来保证顺序。但是,我相信如果我需要在静态类中声明变量(例如,控制台应用程序的 Program.cs,它有一个静态 void Main() 过程而不是构造函数),这种方法是不可能的。

更新:

我已经添加了 static 关键字(因为这是我正在使用的以及它编译的原因)以及 Path.Combine 的建议。

【问题讨论】:

  • 为什么不让他们const?使用const,您可以放心。
  • 这些路径可能成为单独程序集中的其他代码所依赖的程序集的一部分。这些路径可能会改变,我希望能够做到这一点,而不必重新编译依赖这些路径值的其余程序集。使用常量我别无选择,只能重新编译所有内容,而不仅仅是 DLL。

标签: c# .net-3.5 readonly variable-declaration


【解决方案1】:

顺序不重要。运行时保证所有对象在使用时都被初始化。

您的具体案例实际上是不可编译的,因为这无法保证。

您对构造函数方法的看法是正确的。如果你需要这个静态变量也没问题,因为你可以指定一个静态构造函数。

顺便说一句:连接目录的正确方法是使用 Path.Combine 而不是字符串连接。

【讨论】:

  • 我忘记了 Path.Combine 方法。谢谢提醒。
  • 问题在给出这个答案后更新。当问题字段为static时,文本顺序非常重要。然后初始化程序按文本顺序运行。所以这个答案对static 字段具有误导性。 (静态或非静态在这里很重要;只读与否无关紧要。)
【解决方案2】:

“有可能吗..”

不,编译器不允许您从 subpath1/2 声明访问 basepath。您可以使用常量而不是只读变量来做到这一点。

【讨论】:

  • 说编译器不让我说你是说代码不会编译?它确实为我编译。
  • 刚试了一下,我得到“A field initializer cannot reference the non-static field, method, or property...”。
  • 我明白了。事实证明,在这种情况下,这些实际上是我正在使用的静态只读字符串,所以这就解释了为什么我得到的结果与你不同。
  • 喜欢因为第一个回答与后面条目中相同的信息而被否决。这个系统让我感到困惑。
  • 是我的错。我给你+1是为了取消给你-1的人。它确实有所作为,因此您的答案对于原始问题并不正确。
【解决方案3】:

我怀疑你实际上想使用常量:

    const string basepath = @"my\base\directory\location";
    const string subpath1 = basepath + @"\abc\def";
    const string subpath2 = basepath + @"\ghi\klm";

无论代码中的声明顺序如何,subpath1/2 肯定都会有填充的 basepath 前缀。

【讨论】:

  • 我总是纠结于常量和只读。我读过很多东西,如果它们有可能改变,就不要使用常量。这些路径可能成为其他代码所依赖的程序集的一部分。我希望能够更改这些路径,而不必重新编译依赖这些路径值的其余程序集。使用常量我别无选择,只能重新编译所有内容,而不仅仅是 DLL。