簡體   English   中英

首先運行的字段初始化器(是否靜態)和構造函數(是否靜態)

[英]Fields Initilizers (Static or not) and Constructor (Static or not) which one runs first

根據我閱讀的內容,我不清楚:

  1. Field Initializers在構造函數之前運行。
  2. Static field Initializers在調用static constructor之前執行(仍然與第1點兼容)。
  3. 如果一個類型沒有靜態構造函數,則將在使用該類型之前執行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。

我不能真正遵循此邏輯,請向我澄清。

編輯:我期望發生的事情:

  1. 當Foo.X時:執行:公共靜態Foo實例= new Foo();
  2. 在調用打印的構造函數之前(“在構造函數中:” + X),public static int X = 3; 應該執行,但是碰巧構造函數首先觸發,難道不是字段首先運行完成? 我的意思是,即使在跳入內部創建新的Foo實例時,也必須首先運行字段。
  3. 從最后兩個點,我希望先打印3然后3

如果一個類型沒有靜態構造函數,則將在使用該類型之前執行字段初始化程序(據我所知:不是被實例化而是被使用)

不必要。

如果沒有靜態構造函數,則靜態字段初始化將在靜態字段前一段時間被執行第一次使用-但靜態字段初始沒有被創建的所有實例之前執行。

根據C#5規范的第10.5.5.1節:

類的靜態字段變量初始值設定項對應於以文本順序執行的分配序列,這些賦值序列出現在類聲明中。 如果類中存在靜態構造函數(第10.12節),則在執行該靜態構造函數之前立即執行靜態字段初始化程序。 否則,將在首次使用該類的靜態字段之前,在與實現相關的時間執行靜態字段初始化程序。

但是在您的情況下,您只是看到調用Foo的構造函數以初始化InstanceX仍為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM