2012-08-15 74 views
28

我創建了一個「常量」的數值之前明確地在我的代碼說明了幾次:爲什麼會這樣編譯?

private static readonly int QUARTER_HOUR_COUNT = 96; 

當我做了96 QUARTER_HOUR_COUNT搜索和替換,我無意中也換成了聲明,所以它成爲:

private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT; 

......但它編譯。我會認爲它會不允許的。爲什麼編譯器接受它作爲有效的聲明?

+0

因爲它的靜態! – canon 2012-08-15 16:27:37

+0

哇!這確實是令人驚訝的行爲。 – leppie 2012-08-15 16:27:43

+0

,因爲有無數的方法來做錯。 – Jodrell 2012-08-15 16:43:04

回答

23

I would think that it would disallow that. Why was it accepted by the compiler as a valid declaration?

大概是因爲語言規範允許它。在你認爲禁止的語言規範中是否有特定的規則?

如果您的問題真的是「爲什麼不語言規範禁止這種」 - 我懷疑這是因爲它可能相當困難,以確保您禁止你真的要禁止的事情,而實際上禁止一切事情。

你可以說,對於簡單案件分配的直接回自己,這將是件好事,在語言規範中的一個特例,但它會引入複雜性到語言相對沒有什麼好處。

請注意,即使你沒有得到一個錯誤,我希望你能獲得一個警告 - 是這樣的:

Test.cs(3,33): warning CS1717: Assignment made to same variable; did you mean to assign something else?

另外請注意,如果你把它一const代替只是一個靜態只讀變量,那麼你得到一個編譯時錯誤:

Test.cs(3,23): error CS0110: The evaluation of the constant value for 'Program.QUARTER_HOUR_COUNT' involves a circular definition

還要注意,通過.NET命名約定,這應該被稱爲QuarterHourCount,而不是SHOUTY_NAME。

+1

未分配的變量的用法我會想。 – leppie 2012-08-15 16:28:58

+3

@leppie:不適用於靜態字段初始值設定項中的靜態字段。術語「未賦值變量」對靜態字段沒有意義,靜態字段沒有明確的賦值概念。 – 2012-08-15 16:29:52

+0

實際上,它們是按照它們定義的順序初始化的。 IMO違反了這條規則 – leppie 2012-08-15 16:31:38

5

因爲該變量初始化爲0,然後設置爲自己。

我的猜測是,它會在設置爲自己之前做一個新的Int(),將它初始化爲零。

4

因爲編譯器將打破這條線下來:

private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT; 

基本上到IL等價的:

private static readonly int QUARTER_HOUR_COUNT; 
QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT; 

然後顯然是會得到更多的太破了,但上面的應該足以說明我的觀點。

從技術上講,在它被使用時它的默認值爲零。

0

由於其他人具有隱含的值類型,如int有一個默認值,所以聲明一個變量而不顯式初始化它意味着它仍然有一個值。

你可以找到任何類型的默認值,像這樣:

int i = default(int); 

或者更一般地說:

T t = default(T); 

注意,引用類型的默認將null,只值類型將有默認值。

6

由代碼生成的IL代碼是這樣的:

IL_0007: ldsfld  int32 Example.Quat::QUARTER_HOUR_COUNT//Load the value of a static field on the stack 
IL_000c: stsfld  int32 Example.Quat::QUARTER_HOUR_COUNT// Store the value from the stack in the static field 

由於QUARTER_HOUR_COUNT的默認值是0,0被分配到QUARTER_HOUR_COUNT