【问题标题】:Is the "textual order" across partial classes formally defined?是否正式定义了跨部分类的“文本顺序”?
【发布时间】:2011-11-01 11:36:14
【问题描述】:

具体而言,与字段初始化器(在本例中为静态)有关 - ECMA 334 中的第 17.11 节:

如果一个类包含任何带有初始化器的静态字段,则这些初始化器会在执行静态构造函数之前以文本顺序立即执行。

现在,如果我们在单独的文件中有多个 partial 类,那么该顺序是否在任何地方确定?我的直觉说“没有正式定义,但可能与 csproj 中包含的顺序或 csc 中记录的顺序有关”。这是正确的吗?

(是的,我意识到最好完全避免歧义 - 可能通过将所有初始化移动到静态构造函数)。


例如,如果我有a.cs:

using System;
partial class Program
{
    private static int Foo = Write("Foo");
    static int Write(string name)
    {
        Console.WriteLine(name);
        return 0;
    }
    static void Main()
    {
        Console.WriteLine("[press any key]");
        Console.ReadLine();
    }
}

b.cs:

partial class Program
{
    private static int Bar = Write("Bar");
}

和:

<Compile Include="a.cs" />
<Compile Include="b.cs" />

那么这是Foo 然后是Bar;但是,如果这是:

<Compile Include="b.cs" />
<Compile Include="a.cs" />

然后是Bar 然后是Foo。这支持观察,但没有强烈说明。 §8.7.13(部分类型声明)对组合partial 类时的顺序不做评论。所以;从 C# 语言规范或工具文档中,我们可以在这里说什么更强大的东西吗?

此外,csc a.cs b.cscsc b.cs a.cs 的行为类似。

【问题讨论】:

    标签: c# constructor


    【解决方案1】:

    这是 C# 规范中的另一个 sn-p,与您的 sn-p 一起使用,似乎可以确定这是未定义的行为:

    10.2.6 成员

    [...] 类型中成员的排序很少对 C# 代码,但在与其他语言交互时可能很重要 和环境。在这些情况下,成员在一个 多部分声明的类型未定义。

    公平地说,它确实说很少重要,而不是微不足道:)。

    【讨论】:

    • “类型中成员的排序对于 C# 代码来说很少重要” - whaaaa?不!这对于字段初始化顺序非常重要,尤其是当一个static readonly 字段基于另一个静态字段进行初始化时。
    【解决方案2】:

    我知道这个问题很老了,但这里是规范的正确部分:

    ECMA-334(C# 语言规范),变量初始化器,第 17.4.5 节:

    当有多个部分类型的字段声明时 相同类型的声明,部分的顺序是未指定的。 但是,在每个部分中,字段初始值设定项都在 顺序。

    所以 partial 类型中的“文本顺序”不是未定义的,而是 partially 定义的。 ;-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-09
      • 1970-01-01
      • 1970-01-01
      • 2011-03-28
      • 2012-03-03
      • 1970-01-01
      • 2015-12-29
      • 2013-04-04
      相关资源
      最近更新 更多