为什么不能在结构体内初始化非静态字段?
考虑这个代码块:
struct Animal { public string name = ""; // Error public static int weight = 20; // OK // initialize the non-static field here public void FuncToInitializeName() { name = ""; // Now correct } }
- 为什么我们可以初始化结构中的
static
字段而不non-static
字段? - 为什么我们必须在方法体中初始化
non-static
?
看看为什么不能有值类型有默认构造函数?
CLI期望能够分配和创建任何需要’n’个字节内存的值类型的新实例,只需分配’n’个字节并用零填充它们。 没有理由CLI“无法”提供一种方法来指定在包含结构的任何实体可用于外部代码之前,必须在其中的每个结构上运行构造函数,或者每当某个特定n的实例运行时创建了字节结构,编译器应该复制一个’模板实例’。 然而,实际上,CLI不允许这样的事情。 因此,编译器没有理由假装它有一种方法可以确保将结构体初始化为除了内存填充为零的默认值之外的任何内容。
您无法在结构中编写自定义默认构造函数。 实例字段初始值设定项最终需要移动到您无法定义的构造函数。
静态字段初始值设定项将移动到静态构造函数。 您可以在结构中编写自定义静态构造函数。
你可以完全按照自己的意愿行事。 您所缺少的是一个调用默认构造函数的自定义构造函数:
struct Animal { public string name = ""; public static int weight = 20; public Animal(bool someArg) : this() { } }
构造函数必须至少使用一个参数,然后必须转发到this()
以初始化成员。
这样做的原因是编译器现在有办法发现代码应该运行以初始化name
字段的时间:每当你编写new Animal(someBool)
。
对于任何结构,您可以说new Animal()
,但在CLR的工作中,可以在许多情况下隐式创建“空白”动物,并且没有办法确保每次发生时自定义代码都会运行。