2011-11-08 40 views
1

這個方法是一個在aspx GridView控件中的OnRowCommand的事件處理程序。 Resharper警告說,gvUnits,gvUnit.DataKeysgvUnits.DataKeys[index]可能爲空,並建議在第2條if語句中添加檢查。一旦添加,它會創建一個額外的警告,gvUnits.DataKeys != null始終爲真。既沒有按照它的建議來添加這些檢查,也沒有手動添加斷言來抑制警告。爲什麼resharper仍然給這個代碼的空引用警告

我不明白這是怎麼回事:是gvUnits易變,如果是這樣,爲什麼,它是一個在resharper 5.1中的bug,還是其他的事情呢?

protected void GvUnitsRowCommand(object sender, System.Web.UI.WebControls.GridViewCommandEventArgs e) 
{ 
    if (e.CommandName == "EditUnit") 
    { 
     int index = int.Parse(e.CommandArgument.ToString()); 
     if (gvUnits != null && gvUnits.DataKeys != null && gvUnits.DataKeys.Count > index) 
     { 
      Debug.Assert(gvUnits != null); 
      Debug.Assert(gvUnits.DataKeys != null); 
      Debug.Assert(gvUnits.DataKeys[index] != null); 

      int unitID = (int)gvUnits.DataKeys[index].Value; 
      //do stuff with unitID 
     } 
    } 
} 

回答

6

假設DataKeys是一個屬性,然後gvUnits.DataKeys本質上是一個方法調用(調用一個getter。)因此,如果你把它叫做兩次,也不能保證它不會在第二次調用返回null 。同樣,如果DataKeys[index]是一個索引器調用(不是數組訪問),那麼這也是一個方法調用,如上所述,它可以在第二次調用時返回null。提供保證斷言的唯一方法是將每個調用的結果存儲在局部變量中,然後斷言本地值不爲空。由於本地價值在用法之間不能改變,ReSharper知道它是安全的。

這是一種在沒有意識到的情況下做出隱式假設的情況(屬性的返回值在調用之間不會發生變化)。如果您願意,可以使用註釋來壓制警告,而不是創造一個斷言,這基本上推的假設上的財產執行者的本地副本(保證連續調用之間的非可變性。)

+0

我檢查並且DataKeys是通過索引器方法訪問的屬性。現在有道理; resharper可能有點聰明,不建議生成一個不起作用的'修復'(在這裏是v6更好嗎?)。 –

1

檢查:如果null輸入嘗試使用 int.Parse(int)將失敗Convert.ToInt32

if (e.CommandName == "EditUnit") 
{ 
    int index = Convert.ToInt32(e.CommandArgument); 
    DataKey key = GridView1.DataKeys[index]; 
    if (key!=null) 
    { 
     int id = Convert.ToInt32(key.Value); 
    } 
} 
+0

Resharper不喜歡你的代碼比它更喜歡我的代碼。我認爲丹·布萊恩特對於發生的事情有正確的解釋。 –

+0

@DanNeely更新,我犯了一個錯誤 – Damith

+0

這很有效。謝謝。 –

相關問題