¿Por qué resharper sigue dando advertencias de referencia nula para este código?

Este método es un controlador de eventos para OnRowCommand en un control aspx GridView. Resharper advierte que gvUnits, gvUnit.DataKeysy gvUnits.DataKeys[index] podría ser nulo y sugiere agregar las comprobaciones en la segunda instrucción if. Una vez que se agregan, crea una advertencia adicional que gvUnits.DataKeys != null siempre es cierto. Ni agregar estas comprobaciones como se sugirió, ni agregar manualmente las afirmaciones suprimió las advertencias.

No entiendo lo que está pasando aquí: gvUnits es volátil y, de ser así, ¿por qué, es un error en resharper 5.1 o hay algo más?

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

preguntado el 08 de noviembre de 11 a las 16:11

2 Respuestas

Asumiendo que DataKeys es una propiedad, entonces gvUnits.DataKeys es esencialmente una llamada a un método (que llama a un captador). Como tal, si lo llama dos veces, no hay garantía de que no devuelva un valor nulo en la segunda llamada. Asimismo, si DataKeys[index] es una llamada de indexador (no un acceso a una matriz), también es una llamada a un método, que puede, como antes, devolver un valor nulo en una segunda llamada. La única forma de proporcionar una aserción garantizada es almacenar el resultado de cada llamada en una variable local y luego afirmar que el valor local no es nulo. Dado que el valor local no puede cambiar entre usos, ReSharper sabe que es seguro.

Este es uno de esos casos en los que está haciendo una suposición implícita sin siquiera darse cuenta (que el valor de retorno de una propiedad no cambiará entre llamadas). Puede suprimir la advertencia con un comentario, si lo desea, en lugar de crear un copia local para una aserción, que básicamente empuja la suposición al implementador de la propiedad (para garantizar la no mutabilidad entre llamadas consecutivas).

respondido 08 nov., 11:20

Verifiqué y DataKeys es una propiedad a la que se accede a través de un método indexador. Eso tiene sentido ahora; resharper podría ser un poco más inteligente para no sugerir generar una 'solución' que no funciona (¿la v6 es mejor aquí?). - Dan está jugando a la luz del fuego

Mira esto: int.Parse y (int) fallará si null entrada intente usar 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);
    }
}

respondido 08 nov., 11:21

A Resharper no le gusta su código más de lo que le gusta el mío. Creo que Dan Bryant tiene la explicación correcta de lo que está sucediendo. - Dan está jugando a la luz del fuego

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.