[英]Fields Initilizers (Static or not) and Constructor (Static or not) which one runs first
根據我閱讀的內容,我不清楚:
Field Initializers
在構造函數之前運行。 Static
field Initializers
在調用static
constructor
之前執行(仍然與第1點兼容)。 field Initializers
(據我所知:不是被實例化而是被使用) 這個例子說明:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Foo.X);
Console.ReadLine();
}
}
class Foo
{
public static Foo Instance = new Foo();
public static int X = 3;
Foo()
{
Console.WriteLine("In constructor: " + X);
}
}
此代碼先打印0,然后打印3! 那怎么可能呢? 當我們通過執行Foo.X來使用Foo時,在構造函數之前(到目前為止還可以)調用兩個第一個初始化程序:
public static Foo Instance = new Foo();
被執行后,它應該在調用構造函數之前(第1點)運行自己的2個初始化程序,而它首先運行構造函數並以默認值0輸出X。
我不能真正遵循此邏輯,請向我澄清。
編輯:我期望發生的事情:
如果一個類型沒有靜態構造函數,則將在使用該類型之前執行字段初始化程序(據我所知:不是被實例化而是被使用)
不必要。
如果沒有靜態構造函數,則靜態字段初始化將在靜態字段前一段時間被執行第一次使用-但靜態字段初始沒有被創建的所有實例之前執行。
根據C#5規范的第10.5.5.1節:
類的靜態字段變量初始值設定項對應於以文本順序執行的分配序列,這些賦值序列出現在類聲明中。 如果類中存在靜態構造函數(第10.12節),則在執行該靜態構造函數之前立即執行靜態字段初始化程序。 否則,將在首次使用該類的靜態字段之前,在與實現相關的時間執行靜態字段初始化程序。
但是在您的情況下,您只是看到調用Foo
的構造函數以初始化Instance
, X
仍為0,因為尚未為其分配值。 字段初始值設定項是按文本順序執行的,因此在X
之前為Instance
分配了一個值。 它是那樣簡單-它不是靜態字段和實例字段之間的時序的問題,因為你沒有得到任何實例字段。
編輯:似乎您對構造函數調用感到困惑。 Foo
已經被初始化-構造函數調用不會更改它,並且沒有“第二次初始化”。 構造函數通常被調用,顯示“ 0”,然后返回。 然后為 X
分配值3。
Foo()
構造函數不是靜態構造函數,因此它不會像您的case 3
一樣首先運行。
因此,首先從上到下初始化字段。
第一次static Foo
初始化時,將執行它,然后顯示0
;然后,當X
初始化時,即使用System.Console.WriteLine()
調用來打印。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.