This method is an event handler for OnRowCommand in an aspx GridView control. Resharper warns that gvUnits, gvUnit.DataKeys, and gvUnits.DataKeys[index] could be null, and suggests adding the checks in the 2nd if statement. Once they’re added it creates an additional warning that gvUnits.DataKeys != null is always true. Neither adding these checks as it suggested, nor manually adding the asserts suppressed the warnings.
I don’t understand what’s going on here: is gvUnits volatile and if so why, is it a bug in resharper 5.1, or is something else going on?
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
}
}
}
Assuming that
DataKeysis a property, thengvUnits.DataKeysis essentially a method call (calling a getter.) As such, if you call it twice, there is no guarantee that it will not return null on the second call. Likewise, ifDataKeys[index]is an indexer call (not an array access), this is also a method call, which can, as above, return null on a second call. The only way to provide a guaranteed assertion is to store the result of each call in a local variable, then Assert that the local value is not null. Since the local value cannot change between usages, ReSharper knows it is safe.This is one of those cases where you’re making an implicit assumption without even realizing it (that the return value of a property will not mutate between calls.) You can suppress the warning with a comment, if you wish, rather than creating a local copy for an assertion, which basically pushes the assumption onto the property implementor (to guarantee the non-mutability between consecutive calls.)