2010-12-08 11 views
7

Aquí es una pieza de código:ReSharper: cómo quitar "posible" System.NullReferenceException" advertencia

 IUser user = managerUser.GetUserById(UserId); 
     if (user==null) 
      throw new Exception(...); 

     Quote quote = new Quote(user.FullName, user.Email); 

Todo está bien aquí. Pero si reemplazo "si" de acuerdo con la siguiente:

 ComponentException<MyUserManagerException>.FailIfTrue(user == null, "Can't find user with Id=" + UserId); 

donde implementación de la función es el siguiente:

public abstract class ComponentException<T> : ComponentException 
     where T : ComponentException, new() 
{ 
    public static void FailIfTrue(bool expression, string message) 
    { 
     if (expression) 
     { 
      T t = new T(); 
      t.SetErrorMessage(message); 
      throw t; 
     } 
    } 
    ... 
} 

Entonces ReSharper me genera una advertencia: Posible 'System.NullReferenceException' que señala en la primera utilización del objeto 'usuario'.

Q1. ¿Por qué genera tal excepción? Por lo que veo si 'user == null' se generará una excepción y la ejecución nunca llegará al punto de uso.

Q2. ¿Cómo eliminar esa advertencia? Tenga en cuenta: 1. No quiero suprimir esta advertencia con comentarios (tendré muchas piezas similares y no quiero transformar mi código fuente en 'garbas comentó); 2. No quiero cambiar la configuración de la nueva configuración para cambiar este problema de advertencia a 'sugerencia' de 'pista'.

Gracias.

¡Cualquier pensamiento es bienvenido!

P.S. Estoy usando el reajuste 5.1, MVSV 2008, C#

Respuesta

6

Q1: Porque Resharper no analiza el camino. Solo ve una posible referencia null y señala eso.

Q2: No puede hacerlo sin hacer lo que ya ha proporcionado.

0

Esto es causado por el motor Resharper. Estas "posibles NullReferenceException" ocurren porque alguien (probablemente en Resharper) ha declarado/configurado en alguna parte una anotación sobre el método.

Así es como funciona: ReSharper NullReferenceException Analysis and Its Contracts

Desafortunadamente, a veces, estas anotaciones útiles son simplemente incorrecto.

Cuando detecta un error, debe informarlo a JetBrains y ellos actualizarán las anotaciones en la próxima versión. Están acostumbrados a esto.

Mientras tanto, puede intentar solucionarlo usted mismo. Lea el artículo para obtener más información:

10

Resharper solo analiza el método actual para su análisis y no analiza recursivamente otros métodos que usted llame.

Sin embargo, puede dirigir Resharper un poco y darle meta-información sobre ciertos métodos. Sabe, por ejemplo, sobre "Assert.IsNotNull (a)", y tendrá en cuenta esa información para el análisis. Es posible crear un archivo de anotaciones externas para Resharper y darle información adicional sobre cierta biblioteca para mejorar su análisis. Tal vez esto podría ofrecer una manera de resolver su problema.

Más información se puede encontrar here.

Un ejemplo que muestra cómo se usa para la biblioteca Microsoft.Los contratos se pueden encontrar here.

3

Usted sabe (o espera) que este código producirá una excepción si hay una referencia nula:

ComponentException<MyUserManagerException>.FailIfTrue([...]); 

Sin embargo, dado que no existe un contrato que especifica esto, ReSharper tiene que asumir que esto es sólo una llamada al método normal que puede regresar sin arrojar ninguna excepción en ningún caso.

hacen que este método poner en práctica el contrato ReSharper, o como una solución simple (que sólo afecta a modo de depuración, por lo tanto, sin penalizar el rendimiento de modo de liberación), justo después de la llamada FailIfTrue:

Debug.Assert(user != null); 

que logrará erradicar de la advertencia, y como una ventaja adicional haga una verificación de tiempo de ejecución en modo de depuración para asegurarse de que la condición asumida por usted después de llamar al FailIfTrue se cumpla.

+0

deseaba era cierto ... ReSharper 5.1 no identifica correctamente 'Debug.Assert (usuario! = Null);' y eleva la advertencia. ¿Hay alguna configuración que deba hacer? –

+0

Uh, R # 5.1 está bastante desactualizado, así que no tengo nada para poner a prueba su problema. Sin embargo, algunos consejos: asegúrese de que su código se refiera apropiadamente a la clase 'System.Diagnostics.Debug' ya que el contrato del código fue definido para eso, y no para métodos arbitrarios con ese nombre/firma. Además, asegúrese de que la configuración de compilación esté configurada en Depurar (de lo contrario, el código quedará fuera del alcance y, por lo tanto, aparecerá la advertencia). – Lucero

+0

'Debug.Assert' funciona, pero solo en el modo de depuración. –

4

una nueva respuesta en el antiguo puesto ...

Aquí una pequeña muestra de mi código con respecto a cómo utilizar CodeContract través ContractAnnotation con ReSharper:

[ContractAnnotation("value:null=>true")] 
    public static bool IsNullOrEmpty(this string value) 
    { 
     return string.IsNullOrEmpty(value); 
    } 

Es muy simple ... si u encuentra el pan rallado en la madera. Usted puede verificar otros casos también.

tenga un buen día

+1

Si sabe que un método siempre arroja una excepción, puede hacer '[ContractAnnotation (" => halt ")]' – Dejan

Cuestiones relacionadas