繁体   English   中英

为什么Resharper仍然为此代码提供空引用警告

[英]Why is resharper still giving null reference warnings for this code

此方法是aspx GridView控件中OnRowCommand的事件处理程序。 Resharper警告gvUnitsgvUnit.DataKeysgvUnits.DataKeys[index]可能为null,并建议在第二个if语句中添加检查。 添加它们后,它会创建一个附加警告,即gvUnits.DataKeys != null始终为true。 既不按照建议添加这些检查,也没有手动添加断言抑制了警告。

我不明白这是怎么回事:gvUnits是易失性的,如果是这样,为什么是Resharper 5.1中的错误,还是有其他问题?

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
        }
    }
}

假设DataKeys是一个属性,则gvUnits.DataKeys本质上是一个方法调用(调用getter)。因此,如果您两次调用它,则不能保证它在第二次调用时不会返回null。 同样,如果DataKeys[index]是索引器调用(而不是数组访问),则这也是方法调用,如上所述,它可以在第二次调用中返回null。 提供保证的断言的唯一方法是将每次调用的结果存储在局部变量中,然后断言该局部值不为null。 由于本地值在使用之间无法更改,因此ReSharper知道它是安全的。

在这种情况下,您甚至没有意识到就做出了隐式假设(属性的返回值不会在调用之间发生变化)。在这种情况下,您可以根据需要添加注释,而不用创建警告。断言的本地副本,它基本上将假设推到属性实现器上(以保证连续调用之间的不可变性。)

检查一下:如果尝试使用Convert.ToInt32输入nullint.Parse(int)将失败

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM