4

这个问题的灵感来自 Jon Skeet 的回答: Is there ac# equivalent to c++'s access-modifier region

他评论说文件中字段的顺序可能很重要。我猜这与字段初始化的顺序有关,但我认为基于这种副作用进行编码是一件足够危险的事情,它需要自己的问题和讨论。

关于如何操纵代码文件中的字段顺序以及可能产生什么影响,是否还有其他想法?

4

6 回答 6

25

这是 C# 语言规范中的一个经典示例(第 10.5.5 节)

class Test
{
    static int a = b + 1;
    static int b = a + 1;
    static void Main() {
        Console.WriteLine("a = {0}, b = {1}", a, b);
    }
}

这是一个完全有效的程序,如所写(a = 1,b =2)。但是,如果您交换字段的顺序,它们也会交换值。

于 2009-01-10T16:15:07.153 回答
3

是的,与非托管代码交互时确实很重要。

于 2009-01-10T16:08:26.590 回答
2

我主要是在考虑初始化的顺序,是的 - 特别是对于静态字段。例如(使用公共字段只是为了简化演示):

using System;

class First
{
    static int a = 10;
    public static int b = CalculateB();
    static int c = 5;

    static int CalculateB()
    {
        return a*c;
    }
}

class Second
{
    static int a = 10;
    static int c = 5;
    public static int b = CalculateB();

    static int CalculateB()
    {
        return a*c;       
    }
}

class Test
{
    static void Main()
    {
        Console.WriteLine("First.b: {0}, Second.b: {1}",
                          First.b, Second.b);
    }
}

初始化的顺序在规范中定义为声明变量的文本顺序 - 但是当两个变量位于对部分类有贡献的不同文件中时,它变得未定义。

Mehrdad 的回答是另一个好答案:任何对物理布局很重要的东西都很可能会受到声明顺序的影响。

于 2009-01-10T16:13:28.733 回答
1

如果字段被初始化为声明的一部分,它们会按照它们在文件中出现的顺序添加到构造函数(实例或静态)中。

于 2009-01-10T16:14:17.033 回答
0

您可以使用(滥用?)字段顺序作为类的元数据,而不是通过反射读取。

例如,如果您有一个类表示具有字段 ID、PORT 和 XOR 的网络协议,按照该顺序,您可以将其定义为:

class MyProtocol {
    int ID;
    int PORT;
    int XOR;
}

现在假设您使用反射来迭代协议的字段,以通过线路发送。GetProperties 返回的顺序将与您定义的一样,您不必显式编写任何额外的元数据。

不知道这是否是一个好主意,但依赖于此。

于 2009-01-10T16:55:07.993 回答
0

我相信 XmlSerializer 按照它们在源文件中出现的顺序对成员进行序列化。

于 2009-01-10T17:34:25.420 回答