2010-05-18 8 views
6

Tengo un código muy simple (simplificado del código original, así que sé que no es un código muy inteligente) que cuando compilo en Visual Studio 2010 con Code Analysis me da una advertencia CA1062: Valida los argumentos de los métodos públicos.¿Por qué obtengo Code Analysis CA1062 en un parámetro out en este código?

public class Foo 
{ 
    protected static void Bar(out int[] x) 
    { 
     x = new int[1]; 
     for (int i = 0; i != 1; ++i) 
      x[i] = 1; 
    } 
} 

La advertencia me sale:

CA1062: Microsoft.Design: En método visible externamente 'Foo.Bar (fuera int [])', validar variable local '(x *) ', que fue reasignado del parámetro' x ', antes de usarlo.

No entiendo por qué aparece esta advertencia y cómo puedo resolverla sin suprimirla? ¿Puede new devolver null? ¿Es esto un error de Visual Studio 2010?

ACTUALIZACIÓN

he decidido abrir a bug report on Microsoft Connect.

+0

Me pregunto si el problema está en otra parte ... –

+0

nuevo no repro. No hay nada que validar Ha publicado otras advertencias de análisis de código que no reproducen. Si ha realizado cambios en la configuración, asegúrese de documentarlos. –

+0

@ Hans Passant, ¿está seguro de que está ejecutando todas las reglas de análisis de código de Microsoft en Visual Studio 2010? – brickner

Respuesta

8

He reproducido esto en Visual Studio 2010 Premium con el código exactamente como se indica y con Microsoft All Rules habilitado en la configuración de análisis.

Parece que se trata de un error (ver abajo de aquí: http://msdn.microsoft.com/en-us/library/ms182182.aspx). Se queja de que no está comprobando que x no es nulo antes de usarlo, pero está en el parámetro out, por lo que no hay ningún valor de entrada para verificar.

5

Es fácil mostrar que describir:

public class Program 
{ 
    protected static int[] testIntArray; 

    protected static void Bar(out int[] x) 
    { 
     x = new int[100]; 
     for (int i = 0; i != 100; ++i) 
     { 
      Thread.Sleep(5); 
      x[i] = 1; // NullReferenceException 
     } 
    } 

    protected static void Work() 
    { 
     Bar(out testIntArray); 
    } 

    static void Main(string[] args) 
    { 
     var t1 = new Thread(Work); 
     t1.Start(); 

     while (t1.ThreadState == ThreadState.Running) 
     { 
      testIntArray = null; 
     } 
    } 
} 

Y la manera correcta es:

protected static void Bar(out int[] x) 
    { 
     var y = new int[100]; 

     for (int i = 0; i != 100; ++i) 
     { 
      Thread.Sleep(5); 
      y[i] = 1; 
     } 

     x = y; 
    } 
+0

bien, pero ¿por qué es la forma correcta? ¿O dice que es correcto porque no hay una advertencia en el análisis del código? –

+0

Lo que has mostrado es sin duda un punto importante (si se puede acceder a x por varios hilos), pero no creo que esto sea lo que el CA1062 pretende resaltar. Si usted lee la documentación aquí: http://msdn.microsoft.com/en-us/library/ms182182.aspx, es obvio que esto está destinado a los parámetros 'ref' y es solo un estándar; compruebe que no es nulo antes de usarlo. "regla. Es un error que se está aplicando a los parámetros de "salida". ¿Esto realmente previene la advertencia CA1062? –

+0

@gmagana: La forma correcta es segura para hilos y no lanzará NullReferenceException sin importar qué. – Diadistis

Cuestiones relacionadas