简体   繁体   English

为什么不能在结构体内初始化非静态字段?

[英]Why can't non-static fields be initialized inside structs?

Consider this code block: 考虑这个代码块:

struct Animal
{
    public string name = ""; // Error
    public static int weight = 20; // OK

    // initialize the non-static field here
    public void FuncToInitializeName()
    {
        name = ""; // Now correct
    }
}
  • Why can we initialize a static field inside a struct but not a non-static field? 为什么我们可以初始化结构中的static字段而不non-static字段?
  • Why do we have to initialize non-static in methods bodies? 为什么我们必须在方法体中初始化non-static

The CLI expects to be able to allocate and create new instances of any value type that would require 'n' bytes of memory, by simply allocating 'n' bytes and filling them with zero. CLI期望能够分配和创建任何需要'n'字节内存的值类型的新实例,只需分配'n'个字节并用零填充它们。 There's no reason the CLI "couldn't" provide a means of specifying either that before any entity containing structs is made available to outside code, a constructor must be run on every struct therein, or that a whenever an instance of a particular n-byte struct is created, the compiler should copy a 'template instance'. 没有理由CLI“无法”提供一种方法来指定在包含结构的任何实体可用于外部代码之前,必须在其中的每个结构上运行构造函数,或者每当某个特定n的实例时在创建字节结构时,编译器应复制“模板实例”。 As it is, however, the CLI doesn't allow such a thing. 然而,实际上,CLI不允许这样的事情。 Consequently, there's no reason for a compiler to pretend it has a means of assuring that structs will be initialized to anything other than the memory-filled-with-zeroes default. 因此,编译器没有理由假装它有一种方法可以确保将结构体初始化为除了内存填充为零的默认值之外的任何内容。

You cannot write a custom default constructor in a structure. 您无法在结构中编写自定义默认构造函数。 The instance field initializers will eventually need to get moved to the constructor which you can't define. 实例字段初始值设定项最终需要移动到您无法定义的构造函数。

Static field initializers are moved to a static constructor. 静态字段初始值设定项将移动到静态构造函数。 You can write a custom static constructor in a struct. 可以在结构中编写自定义静态构造函数。

You can do exactly what you're trying. 可以完全按照自己的意愿行事。 All you're missing is a custom constructor that calls the default constructor: 您所缺少的是一个调用默认构造函数的自定义构造函数:

struct Animal
{
    public string name = ""; 
    public static int weight = 20; 

    public Animal(bool someArg) : this() { }
}

The constructor has to take at least one parameter, and then it has to forward to this() to get the members initialised. 构造函数必须至少使用一个参数,然后必须转发到this()以初始化成员。

The reason this works is that the compiler now has a way to discover the times when the code should run to initialise the name field: whenever you write new Animal(someBool) . 这样做的原因是编译器现在有办法发现代码应该运行以初始化name字段的时间:每当你编写new Animal(someBool)

With any struct you can say new Animal() , but "blank" animals can be created implicitly in many circumstances in the workings of the CLR, and there isn't a way to ensure custom code gets run every time that happens. 使用任何结构你可以说new Animal() ,但是在CLR的工作中可以隐式地创建“空白”动物,并且没有办法确保每次发生时自定义代码都会运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM