2011-06-02 27 views
25

採用了一塊這樣的代碼,編譯器會抱怨上c.MyProperty修復了使用空分配的'未分配本地變量的使用'。爲什麼?

MyClass c; 

try { throw new Exception(); } 
catch (Exception) { } 

c.MyProperty = 2; // "Use of unassigned local variable 'c'". 

然而,如果你在初始化分配nullc它不會抱怨:

MyClass c = null; 

try { throw new Exception(); } 
catch (Exception) { } 

c.MyProperty = 2; // no complains this time. 

那麼,爲什麼這項工作?如果c未分配null並且編譯器假設允許它,是不是會拋出相同的異常c.MyProperty,未將對象引用設置爲對象的實例

+0

嗯,這很有趣,我的猜測是,雖然該代碼(第二版),仍然會拋出在運行時異常..它是不是撿空分配可能只是一個Visual Studio問題 - 只需一個推測 ? – 2011-06-02 10:13:46

+1

看看http://stackoverflow.com/questions/4770426/non-initialized-vs-null-values-of-reference-types – Haplo 2011-06-02 10:17:31

+1

非常好,優雅地問問題 – user1451111 2017-11-05 10:29:40

回答

53

當您將null分配給變量時,您告訴編譯器退後,因爲您比他知道得更好,所以他不應該抱怨這一點。

這可能是由於分配null被認爲暗示開發人員採取明確行動的事實。

+2

雖然這讓我發笑,我仍然不接近答案。 – 2011-06-02 10:13:05

+13

@Andreas:這是實際的答案,這就是它被允許的原因。 C#會讓你**故意**在腳下自我射擊。它不會讓你無意地這樣做。 – 2011-06-02 10:17:25

+0

儘管我回答的方式是爲我的觀點添加一些幽默,但我真的認爲這可能是編譯器停止抱怨的原因,所以即使在最後階段它不是正確的答案也是有效的答案。 – 2011-06-02 10:18:30

1

想想這樣,編譯器並沒有告訴你它將拋出一個空引用,因此它不能編譯,而是沒有滿足編譯所需的條件之一,即它必須明確分配。

根據規範null是AC#文字:「空字面可以隱式轉換爲引用類型或空類型」

除了在分配的術語:(從規範採取)

開始報價從規範採取用於確定明確賦值 爲了確定每個已使用變量被明確賦值,編譯器

5.3.3精確的規則必須使用與本節中描述的過程相同的過程。

編譯器處理具有一個或多個初始未分配變量的每個函數成員的主體。對於每個初始未賦值的變量v,編譯器在每一個在功能部件的以下幾點確定用於V A明確賦值狀態:

·在每個語句

·的開始在結束點(第8.1節),其將控制轉移到另一個語句或一個語句

·終點在每個表達

·的開始在每一個語句

·在每個圓弧的每個表達式報價

因此,即使空實際上並不指向一個對象在內存的

月底結束,但它滿足被明確指定的要求,這就是爲什麼編譯器允許它。

0

這是因爲C#語言規格v。4.0節1.6.6.2「方法體和局部變量」規定如下:

的方法體可以聲明特定於方法的調用變量。這些變量稱爲局部變量。

[跳過]

C#需要一個局部變量是明確賦值可以得到它的值之前。

這是爲了避免讓你在腳下拍攝自己,就像Binary Worrier整齊地指出的一樣。

0

其原因的例外是,你還沒有爲變量如

if (Request.Files != null && Request.Files.Count > 0) 
      { 
       Image = Request.Files.AllKeys[0]; 
      } 
var stream = new FileStream(Image,FileMode.Open); 

分配一個默認值現在的形象變量會給編譯器錯誤

使用未分配的局部變量「圖片'

這是由於有條件成爲真實的可能性和控制永遠不會知道什麼的原因Image變量是。所以要麼放置一個else塊,要麼像下面那樣指定一個默認值。

string Image = ""; 
if (Request.Files != null && Request.Files.Count > 0) 
      { 
       Image = Request.Files.AllKeys[0]; 
      } 
var stream = new FileStream(Image,FileMode.Open); 
相關問題