2010-05-18 13 views
6

Ich habe einen sehr einfachen Code (vereinfacht aus dem ursprünglichen Code - damit ich weiß, es ist kein sehr cleverer Code), dass, wenn ich in Visual Studio 2010 mit Code-Analyse kompilieren gibt CA1062 Warnung: Argumente der öffentlichen Methoden zu validieren.Warum bekomme ich Code-Analyse CA1062 auf einen out-Parameter in diesem Code?

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

Die Warnung, die ich erhalten:

CA1062: Microsoft.Design: In äußerlich sichtbare Methode 'Foo.Bar (out int [])', validieren lokale Variable ‚(* x) ', die von Parameter' x 'neu zugewiesen wurde, bevor Sie es verwenden.

Ich verstehe nicht, warum bekomme ich diese Warnung und wie kann ich es lösen, ohne es zu unterdrücken? Kann new zurückgeben null? Ist das ein Visual Studio 2010-Fehler?

UPDATE

Ich habe beschlossen, a bug report on Microsoft Connect zu öffnen.

+0

Ich frage mich, ob das Problem an anderer Stelle ist ... –

+0

Wieder kein Repro. Es gibt nichts zu bestätigen. Sie haben andere Codeanalysewarnungen gepostet, die nicht repro vorgehen. Wenn Sie Konfigurationsänderungen vorgenommen haben, sollten Sie diese dokumentieren. –

+0

@Hans Passant, sind Sie sicher, dass Sie alle Microsoft Code-Analyse-Regeln in Visual Studio 2010 ausführen? – brickner

Antwort

8

Ich habe dies in Visual Studio 2010 Premium mit dem Code genau wie angegeben reproduziert und mit Microsoft All Rules in den Analyseeinstellungen aktiviert.

Es sieht so aus, als ob dies ein Fehler ist (siehe unten hier: http://msdn.microsoft.com/en-us/library/ms182182.aspx). Es ist bedenklich, dass Sie nicht überprüfen, dass x nicht Null ist, bevor Sie es verwenden, aber es ist auf out Parameter, so dass es keinen Eingabewert zu überprüfen gibt!

5

Es ist einfacher, zu zeigen, als zu beschreiben:

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

Und der richtige Weg ist:

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

ok, aber warum ist der richtige Weg richtig? Oder sagen Sie, dass es korrekt ist, weil in der Codeanalyse keine Warnung ausgegeben wird? –

+0

Was Sie gezeigt haben, ist sicherlich ein wichtiger Punkt (wenn auf x von mehreren Threads zugegriffen werden kann), aber ich denke nicht, dass dies CA1062 hervorheben soll. Wenn Sie die Dokumentation hier lesen: http://msdn.microsoft.com/en-us/library/ms182182.aspx, es ist offensichtlich, dass dies für 'ref' Parameter bestimmt ist und nur ein Standard ist" überprüfen Sie, dass es nicht null ist, bevor Sie es verwenden "Regel. Es ist ein Fehler, der auf 'out'-Parameter angewendet wird. Verhindert dies tatsächlich die CA1062-Warnung? –

+0

@gmagana: Der korrekte Weg ist threadsicher und wirft keine NullReferenceException, egal was passiert. – Diadistis