2011-11-08 39 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

这很有效。谢谢。 –

相关问题