C#中字段的顺序重要吗?
这个问题的灵感来自Jon Skeet的回答: 他评论说,文件中字段的顺序可能很重要。我猜这与字段的初始化顺序有关,但我认为基于这种副作用编写代码是一件非常危险的事情,因此有必要提出自己的问题并进行讨论C#中字段的顺序重要吗?,c#,field,specifications,C#,Field,Specifications,这个问题的灵感来自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;
}