开发者

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

开发者 https://www.devze.com 2022-12-20 16:07 出处:网络
Consider this code block: struct Animal { public string name = \"\"; // Error public static int weight = 20; // OK

Consider this code block:

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

    // initialize the no开发者_C百科n-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?
  • Why do we have to initialize non-static in methods bodies?


Have a look at Why Can't Value Types have Default Constructors?


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. 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'. As it is, however, the CLI doesn't allow such a thing. 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.

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).

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消