2011-11-21 14 views
5

Mam następujący kod, który ma nie generuje ostrzeżenie CA1804 (zadeklarowana zmienna nigdy nie jest używana) z analizy kodu (VS2010 Premium):Analiza kodu nie wyświetla ostrzeżenia CA1804 pomimo nieużywanej lokalnej zmiennej łańcuchowej w C# (VS2010 Premium)

... 
if(boolVariable) 
{ 
    string errorText = "Bla Bla Bla"; // Never used 
    ErrorProvider.SetError(SomeControl, "Some Warning"); 
} 
else 
{ 
    string errorText = "Acme Acme Acme"; // Used below 
    ErrorProvider.SetError(SomeControl, errorText); 
} 
... 

Kiedy usunąć ErrorProvider.SetError (...) linie, ostrzeżenie CA1804 jest pokazany, ale dlaczego nie jest to w przypadku próbki kodu powyżej?

(BTW: Sam kod nie jest zbyt wielki i właśnie pokazano, aby zilustrować moje pytanie.)

Jakieś pomysły co może być przyczyną takiego zachowania? Myślę, że to może być w dół na fakt, że kod IL jest zoptymalizowany w taki sposób, że stawia deklarację poza jeżeli, co z kolei oznaczałoby, że ostrzeżenie powinno rzeczywiście nie pokazać się na przykład jak ten powyżej, ale Nie jestem pewien, czy to prawda.

góry dzięki

G.

+0

Prawdopodobnie przesuwa 'ciąg errorText = ...' 'if' zewnątrz i nie zauważysz różnicy między tymi dwoma jednakowo nazwanych zmiennych. Czy nadal kończy się niepowodzeniem, gdy zmieniasz pierwszy "errorText" na "errorText2"? – Polynomial

Odpowiedz

3

To byłoby powodu optymalizacji wykonywanej przez kompilator C#. W wygenerowanym IL, zmienna deklaracja jest podnoszony z bloku if:

string errorText; 
if (boolVariable) 
{ 
    errorText = "Bla Bla Bla"; 
    this.ErrorProvider.SetError(this.SomeControl, "Some Warning"); 
} 
else 
{ 
    errorText = "Acme Acme Acme"; 
    this.ErrorProvider.SetError(this.SomeControl, errorText); 
} 

Usuwanie tylko drugie połączenie SetError jest rzeczywiście wystarczające, aby wywołać CA1804.

BTW, kompilator C# powinien wydać ostrzeżenie CS0219, które najwyraźniej zignorowano. Zdecydowanie polecam potraktowanie ostrzeżeń kompilatora jako błędów, jeśli jesteś zdalnie zainteresowany jakością kodu, który prawdopodobnie przypuszczasz, jeśli korzystasz z Analizy kodu. Po co dodawać dodatkowe narzędzie przesiewowe, zanim wykorzystasz maksimum tego, z którego już korzystasz?

+0

Dziękuję, więc moje przypuszczenie było poprawne. Co do twojej porady CS0219 - nie mogę znaleźć takiego ostrzeżenia w VS2010, gdy CA1804 jest włączony w analizie kodu (poziom ostrzeżenia jest zazwyczaj ustawiony na 4 w naszych projektach). Imho i tak ostrzegają o tym samym wydaniu ("... deklaruje zmienną" ... ", typu" ... ", która nigdy nie jest używana lub jest przypisana tylko ..." vs. "Zmienna" ... "jest przypisany, ale jego wartość nigdy nie była używana."), czy też czegoś tu brakuje? – Gorgsenegger

+0

Nie jestem pewien, dlaczego nie widzisz ostrzeżenia kompilatora. Czy ten konkretny projekt w szczególności nie jest ustawiony na ostrzeżenia na poziomie 4, chociaż większość z nich jest? A może to ostrzeżenie jest wyłączone poprzez konfigurację projektu lub "#pragma ostrzeżenie wyłączone"? Jeśli chodzi o ostrzeżenia CS0219 i CA1804 dotyczące tego samego problemu, ich cel jest taki sam, ale dane, z którymi muszą pracować, są różne (kod źródłowy a IL). Jak już widzieliście, może to prowadzić do różnych wyników. –

+0

W moim pytaniu powyżej kod został nieco skrócony w celach ilustracyjnych. Przetestowałem trochę więcej i dowiedziałem się, że kiedy przypisuję stały ciąg do "errorText" w obu miejscach, jak w [string errorText = "Some fixed string";] Otrzymuję ostrzeżenie kompilatora (CS0219). Jak tylko zmienię to na coś bardziej skomplikowanego, jak w [string errorText = string.Format ("Some variable: {0}", "abc");] ostrzeżenie kompilatora znika i emitowane jest tylko ostrzeżenie o analizie kodu (jeśli analiza kodu jest rzeczywiście uruchomiona). Nie rozumiem tego zachowania. – Gorgsenegger

Powiązane problemy