Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中字段的顺序重要吗?_C#_Field_Specifications - Fatal编程技术网

C#中字段的顺序重要吗?

C#中字段的顺序重要吗?,c#,field,specifications,C#,Field,Specifications,这个问题的灵感来自Jon Skeet的回答: 他评论说,文件中字段的顺序可能很重要。我猜这与字段的初始化顺序有关,但我认为基于这种副作用编写代码是一件非常危险的事情,因此有必要提出自己的问题并进行讨论 关于如何操纵代码文件中字段的顺序以及可能产生的影响,还有其他想法吗?是的,当与非托管代码交互时,这很重要。我主要考虑的是初始化顺序,是的-尤其是静态字段。例如(使用公共字段只是为了简化演示): 规范中的初始化顺序定义为变量声明的文本顺序,但当两个变量位于构成分部类的不同文件中时,初始化顺序将变得

这个问题的灵感来自Jon Skeet的回答:

他评论说,文件中字段的顺序可能很重要。我猜这与字段的初始化顺序有关,但我认为基于这种副作用编写代码是一件非常危险的事情,因此有必要提出自己的问题并进行讨论


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

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

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

规范中的初始化顺序定义为变量声明的文本顺序,但当两个变量位于构成分部类的不同文件中时,初始化顺序将变得未定义


另一个很好的例子是:物理布局很重要的任何内容都很可能会受到声明顺序的影响。

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

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

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

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

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

class MyProtocol {
    int ID;
    int PORT;
    int XOR;
}
现在假设您使用反射来迭代协议的字段,以便通过线路发送。GetProperties返回的顺序将与您定义的相同,并且您不必显式地编写任何额外的元数据


不确定依赖于此是否是一个好主意。

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

好的,是的,我知道,但我忘了,是否也有LayoutKind属性..告诉编译器按特定顺序组织字段。@Josh,有,但是按照正确的顺序声明它们要容易得多Jon skeet有标签,所以?!有必要吗?我认为每个问题都有一个默认标记他有一个我没有创建的标记……我觉得它就在那里,所以为什么不使用它呢,但如果人们愿意,我会删除它。我很惊讶这个编译过程——我希望编译器能够检测到初始化字段的使用(而我更复杂的示例则更难发现)。这是一个很好的简明演示。有趣的是,Java中没有。@Jon,我第一次看到这个示例时也非常惊讶。@Jon:字段从来都不是未初始化的,只有局部变量(和out参数)。字段(静态或其他)始终默认初始化。实际上,这意味着在运行初始值设定项和构造函数之前,包含字段的整个内存区域都已归零。。。。这就是结构不能有实例字段初始值设定项的原因。它将打破默认初始化行为的零。感谢您对您的评论进行扩展;-)这就是我想的,我不可能这么好地表达出来。
class Test
{
    static int a = b + 1;
    static int b = a + 1;
    static void Main() {
        Console.WriteLine("a = {0}, b = {1}", a, b);
    }
}
class MyProtocol {
    int ID;
    int PORT;
    int XOR;
}