2011-04-20 14 views
8

Właśnie znalazłeś błąd w moim programie (po pewnej ilości debugowania i łzawienie moje włosy)C#: Znajdowanie błędów: if (false)

bool first = true; 

foreach (RdAbstractNode node in listNodes) 
{ 
    if (!first) 
    { 
     // do stuff (does not change first) 
    } 
    // do more stuff (does not change first) 
} 

Jak widać first jest zawsze true - nigdy zmienione. Więc if(!first) jest w zasadzie if(false).
Kompilator nie wygenerował ostrzeżenia, mimo że jest ustawiony na poziom 4 (najwyższy poziom).

Jak mogę znaleźć podobne błędy if(false)?

używam VS 2010, .Net 4.0 kompilator, projekt ustawienie .NET 2.0

+2

twoje '// rób rzeczy' może zrobić coś, co mogłoby odwrócić' pierwsze 'ale zobaczyłem, że Resharper wyświetla ostrzeżenia o rzeczach, które zawsze są fałszywe lub prawdziwe. –

+0

lub raczej '// zrobić więcej rzeczy' musiałby być tym, który odwrócił zmienną. – cdeszaq

Odpowiedz

13

Z Resharper dostaniesz ostrzeżenia jak ten

enter image description here

+1

+1 za polecenie Resharper. Jest to kosztowny dodatek dla niektórych, ale jest nieoceniony w takich przykładach. – Pretzel

+0

Czy jest coś darmowego, czy też muszę wydać 42 € na akademicką licencję? –

+0

@Pretzel: "Nieocenione" to odcinek. – jason

10

nie wiem z funkcją kompilatora, które pomogą Ci - trzeba testów jednostkowych.

+0

Kompilator ostrzega o nieprzypisanych zmiennych. Wie, czy zmienna ma stałą wartość. Ale nie ostrzega nawet o 'if (false)' –

+0

@Simon Ottenhaus: Nieprzypisane zmienne są bardzo różne od tych, które tu masz. – jason

+0

Otrzymuję ostrzeżenie kompilacji, jeśli mam blok if (false) z kodem w nim. Jeśli jest w nim tylko komentarz, prawdopodobnie kompilator optymalizuje blok bez ostrzeżenia. Zgadzam się z @dahlbyk: prawdopodobnie chcesz skorzystać z analizy zasięgu kodu lub statycznego analizatora. Jeśli chcesz się dowiedzieć, dlaczego nie jest to ostrzeżenie, ten artykuł może pomóc: http://blogs.msdn.com/b/ericlippert/archive/2011/03/03/danger-will-robinson.aspx – mcw0933

0

Kompilator będzie ostrzegać oczywistych rzeczy jak nieosiągalnego kodu w oparciu o stałą wartość w instrukcji if - przykład "if (false)". Jednakże, ponieważ zmienna może zostać zmieniona, nie zrobi tego w tym przypadku niestety.

1

Zgadzam się, że Resharper jest dobrym narzędziem do posiadania, ale chciałbym dodać, że myślę, że to demonstruje powód, aby NIE używać tej konstrukcji.

Alternatywą może być:

EDIT:

//.net 4.0 
    var firstNode = listNodes.First(); 
     //do something special for first. 

    foreach(var node in listNodes.Skip(1)) 
    { 
     //do something for the rest. 
    } 

//.net 2.0 
using (IEnumerator<RdAbstractNode> enumerator = listNodes.GetEnumerator();) 
{ 
    if (!enumerator.MoveNext()) 
     return; 

    RdAbstractNode first = enumerator.Current; 
    //do something with first 
    while(enumerator.MoveNext()) 
    { 
     RdAbstractNode currentNode = enumerator.Current; 
     //do something with the node. 
    } 
} 

Często znajdujemy się potrzeby mieć jakąś specjalną obsługę dla pierwszego elementu, czasami lepiej jest zmienić logikę i uczynić cały jednolity procesor. Jeśli nie możemy, zawsze wolę wyraźne oddzielenie obsługi specjalnych przypadków od reszty elementów, zamiast zagnieżdżać je.

+0

.Net 2.0: Nie Pomiń (1) –

+0

mm..poprawiono, że - ale można zrobić długi (er) sposób: 'var enumerator = listNodes.GetEnumerator(); enumerator.MoveNext(); var first = enumerator.Current; podczas (enumerator.MoveNext()) { // zrobić coś z wylicznikiem.Current } ' – NightDweller

+0

Zauważ, że' IEnumerator 'powinien zostać usunięty. I w razie potrzeby powinieneś obsłużyć pierwsze wywołanie 'MoveNext()' zwracające 'false'. – dahlbyk