2010-02-21 51 views
20

考慮以下代碼塊:爲什麼不能在結構體中初始化非靜態字段?

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

    // initialize the non-static field here 
    public void FuncToInitializeName() 
    { 
     name = ""; // Now correct 
    } 
} 
  • 爲什麼我們可以初始化一個結構,但不是non-static領域內static場?
  • 爲什麼我們必須在方法體中初始化non-static
+1

是否動物的每個實例重20個單位並且沒有名字?也許你正在尋找一個構造函數。 (請原諒我的術語,如果這是不正確的。) – GManNickG 2010-02-21 06:56:24

+2

這只是示例代碼。 – 2010-02-21 07:02:59

回答

7
+2

雖然在IL級別,他們可以:http://msmvps.com/blogs/jon_skeet/archive/2008/12/10/value-types-and-parameterless-constructors.aspx – 2010-02-21 07:31:51

+0

鏈接現在被打破 – Dominic 2013-09-13 16:26:43

0

您不能在結構中編寫自定義默認構造函數。實例字段初始化器最終需要移動到您無法定義的構造函數中。

靜態字段初始值設定項將移至靜態構造函數。你可以在一個struct中寫一個自定義靜態構造函數。

-1

可以做你想要什麼。所有你缺少的是一個自定義的構造函數調用默認的構造函數:

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

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

構造有至少需要一個參數,然後它轉發給this()得到初始化成員。

其原因是編譯器現在有一種方法來發現代碼應該運行的時間來初始化name字段:每當你寫new Animal(someBool)時。

有了任何結構,你可以說new Animal(),但在CLR的工作中,許多情況下可以隱式地創建「空白」動物,並且沒有辦法確保每次發生時都會運行自定義代碼。

+0

This struct won 't compile'在結構中不能有實例字段初始值設定項「 – 2017-07-12 00:58:01

1

CLI希望能夠通過簡單地分配'n'個字節並將它們填充爲零來分配和創建任何需要'n'字節內存的值類型的新實例。沒有理由CLI「無法」提供一種方法來指定在包含結構的任何實體可用於外部代碼之前,必須在其中的每個結構上運行構造函數,或者每當某個特定的n-字節結構被創建,編譯器應該複製一個'模板實例'。但事實上,CLI不允許這樣的事情發生。因此,編譯器沒有理由假裝它有一種方法來確保結構將被初始化爲除內存填充爲零以外的其他任何內容。