2013-10-14 62 views
3

我是C#編程新手。 請幫幫我。如何將變量存儲在類中以及它們的執行流?

我創建了一個類Tester

class Tester 
{ 
    public int a = 5; 
    public int b = a; 
} 

問題1:爲什麼我不能夠使用這個變量a初始化變量b

問題2:如果我將變量更改爲靜態,那麼它工作正常。爲什麼有差異?

class Tester 
{ 
    public static int a = 5; 
    public static int b = a; 
} 

問題3:在前面的例子中,如果我換變量的順序,然後它工作正常,爲什麼?因爲ab後聲明。它如何初始化a

class Tester 
{ 
    public static int b = a; // 0 
    public static int a = 5; // 5 
} 
+0

閱讀此http://msdn.microsoft.com/en-us/library/aa691162(v=vs.71).aspx和此http://msdn.microsoft.com/en-us/library/aa691161 (v = vs.71).aspx它是關於變量和實例變量 – wudzik

+0

我發現這是一個非常有用的答案:http://stackoverflow.com/questions/1405709/what-is-the-static-variable-initialization -order-in-c –

回答

2

回答1:您不能使用實例變量來初始化另一個實例變量。爲什麼?因爲編譯器可以重新排列這些 - 不能保證變量「a」將在「b」之前被初始化,所以上面的行可能會拋出NullReferenceException異常。

Answer2:它可以正常工作,因爲靜態在其他變量及其引用不被更改之前初始化。

請讓我知道它是否有幫助。

+0

是的,你的信息對我來說是有用的。非常感謝Anirudh –

+0

因此,它意味着靜態變量的初始化順序與它們在代碼中聲明的相同,編譯器在靜態字段的情況下不能進行任何順序更改。但我不認爲這是具有靜態變量的編譯器的正確行爲。 –

1

正如Anirudh所說。您不能使用實例變量來初始化另一個實例變量。爲什麼?由於編譯器可以重新排列這些 - 因此不能保證a將在b之前初始化。

您可以使用此構造函數。

class Tester 
{ 
    public int a=5; 
    public int b; 
    public Tester()//constructor 
    { 
     b=a; 
    } 
} 

class Tester 
{ 
    public static int a = 5; 
    public static int b; 
    public Tester()//constructor 
    { 
     b = a; 
    } 
} 
+0

您的第一段不正確,C#語言確實提供了保證。語言規範中的第10.11.2節「變量初始值設定項是按它們出現在類聲明中的文本順序執行的。」 –

3

當您使用的字段初始化有一些噁心初始化順序的問題。一個簡單的例子是:

class Test { 
    int a = b; 
    int b; 
    public Test() { 
     b = 1; 
    } 
} 

會是怎樣的a價值?如果使用構造函數初始化對象規則,則a將爲1.然而,如果語法的有效性不是這樣,那麼a將爲0。實現字段初始值設定項的副作​​用是將其代碼注入構造函數的主體中的之前的構造函數。當類繼承具有構造函數的基類時,這個問題會變得更加複雜。

這太難看了,C#語言設計者通過簡單地禁止這類代碼來解決這個問題。規則是,您不能在字段初始值設定項中引用這個,該字段初始值設定項會創建對其類構造函數未完成執行的對象的引用。

該規則對於靜態字段是放鬆的,沒有這個引用,並且CLR爲類初始化程序執行順序提供了不錯的保證。然而這並沒有避免含糊不清,這是一個鍛鍊猜測字段值將在這個例子裏:

class Test { 
    static int a = b + 1; 
    static int b = a + 1; 
} 

試試吧,看看你是否可以使結果的意義。否則它是明確的。

相關問題