2010-09-29 17 views
92

Mam plik HTTPSystemDefinitions.cs w projekcie C#, który zasadniczo opisuje starszy system ISAPI okna do konsumpcji według kodu zarządzanego.Tłumienie "nigdy nie jest używane" i "nigdy nie jest przypisane do" ostrzeżeń w C#

Obejmuje to kompletny zestaw struktur istotnych dla ISAPI, które nie są wszystkie lub które są zużywane przez kod. Na kompilacji wszyscy członkowie pola tych struktur są przyczyną ostrzeżenie tak: -

Warning pole „UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.SetHeader” nie jest przypisany do, i zawsze będzie mieć wartość domyślną NULL

lub

Warning polu 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.HttpStatus' nigdy nie jest używany

Czy można je wyłączyć za pomocą #pragma warning disable? Jeśli tak, jakie byłyby odpowiednie numery błędów? Jeśli nie, mogę coś jeszcze zrobić? Pamiętaj, że mam tylko to, co zrobić w tym pliku, ważne, aby zobaczyć ostrzeżenia takie jak te pochodzące z innych plików.

Edycja

Przykład struktura: -

struct HTTP_FILTER_PREPROC_HEADERS 
{ 
    // 
    // For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value. 
    // Header names should include the trailing ':'. The special values 
    // 'method', 'url' and 'version' can be used to retrieve the individual 
    // portions of the request line 
    // 

    internal GetHeaderDelegate GetHeader; 
    internal SetHeaderDelegate SetHeader; 
    internal AddHeaderDelegate AddHeader; 

    UInt32 HttpStatus;    // New in 4.0, status for SEND_RESPONSE 
    UInt32 dwReserved;    // New in 4.0 
} 
+0

Czy możesz pokazać deklarację tych pól, a raczej strukturę, w której się znajdują? to znaczy. daj przykład. –

+0

@Lasse: Dodano przykład. – AnthonyWJones

+8

Jeśli są to definicje międzyoperacyjne, normalnie wstawia się '[StructLayout (LayoutKind.Sequential)]', aby upewnić się, że układ pamięci jest poprawny (w obecnej implementacji będzie nawet bez tego atrybutu, ale AFAIK nie jest gwarantowany). Jeśli dobrze pamiętam, kompilator C# wykrywa obecność tego atrybutu i automatycznie eliminuje te ostrzeżenia, ponieważ wie, że pola muszą tam być dla współdziałania. (Mogłem się mylić w tej sprawie, dlatego zamiast komentarza zamieszczam komentarz). –

Odpowiedz

164

tak, to mogą być tłumione.

Zwykle jestem przeciwny tłumieniu ostrzeżeń, ale w tym przypadku, elementy używane do współdziałania bezwzględnie wymagają obecności pewnych pól, nawet jeśli nigdy nie zamierzacie ich używać (lub mogą z nich korzystać), więc w tym przypadku myślę, że powinno być uzasadnione.

Zwykle w celu zignorowania tych dwóch ostrzeżeń należy naprawić nieprawidłowy kod. Pierwsza ("... nigdy nie jest używana") jest zwykle zapachem kodu resztek z wcześniejszych wersji kodu. Być może kod został usunięty, ale pola pozostały w tyle.

Drugi to zwykle zapach kodu dla nieprawidłowo użytych pól. Na przykład możesz niepoprawnie napisać nową wartość właściwości z powrotem do samej właściwości, nigdy nie pisząc do pola kopii.


Aby stłumić ostrzeżenia dla "Pole XYZ nigdy nie jest używany", to zrobić:

#pragma warning disable 0169 
... field declaration 
#pragma warning restore 0169 

Aby stłumić ostrzeżenia dla "polowego XYZ nie jest przypisane, i zawsze będzie mieć swój domyślna wartość XX”, to zrobić:

#pragma warning disable 0649 
... field declaration 
#pragma warning restore 0649 

Aby znaleźć takie liczby ostrzeżenie siebie (tj.Skąd mam wiedzieć, aby korzystać z 0169 i 0649), to zrobić:

  • kompilacji kodu jako normalne, to będzie dodać kilka ostrzeżeń do listy błędów w Visual Studio
  • Przełącz do okna Output, a Budowanie wyjście, i polowanie na tych samych ostrzeżeń
  • skopiuj 4-cyfrowy kod ostrzegawczy z odpowiednim komunikatem, który powinien wyglądać tak:

    C: \ Dev \ VS.NET \ ConsoleApplication19 \ ConsoleApplication19 \ Program.cs (10,28): ostrzeżenie CS : Pole 'ConsoleApplication19.Program.dwReserved' nigdy nie jest przypisany do i zawsze będzie mieć wartość domyślna 0


Zastrzeżenie: Zgodnie z komentarzem przez @Jon Hanna, może kilka ostrzeżeń jest w tym celu, dla przyszłych poszukiwaczy tego pytania i odpowiedzi.

  • Po pierwsze i przede wszystkim akt tłumienia ostrzeżenia jest podobny do połykania tabletek na ból głowy. Pewnie, czasami może to być słuszne, ale nie jest to rozwiązanie typu "catch-all". Czasami ból głowy jest prawdziwym objawem, którego nie należy maskować, podobnie jak w przypadku ostrzeżeń. Zawsze najlepiej jest traktować ostrzeżenia, naprawiając ich przyczynę, zamiast ślepo usuwać je z danych wyjściowych kompilacji.
  • Powiedziawszy to, jeśli chcesz wyłączyć ostrzeżenie, postępuj zgodnie ze wzorem, który umieściłem powyżej. Pierwsza linia kodu, #pragma warning disable XYZK, wyłącza ostrzeżenie dla reszty tego pliku lub przynajmniej do znalezienia odpowiedniego #pragma warning restore XYZK. Zminimalizuj liczbę linii, w których wyłączono te ostrzeżenia. Powyższy wzorzec wyłącza ostrzeżenie tylko dla jednej linii.
  • Ponadto, jak wspomina Jon, komentarz, dlaczego to robisz, jest dobrym pomysłem. Wyłączenie ostrzeżenia jest bez wątpienia zapachem kodu, gdy jest wykonywane bez przyczyny, a komentarz uniemożliwi przyszłym opiekunom spędzanie czasu, zastanawiając się, dlaczego to zrobiłeś, lub nawet usuwając go i próbując naprawić ostrzeżenia.
+0

To świetnie wiedzieć! –

+8

Polecam dalej powyższej odpowiedzi, że zakres wyłączenia powinien być tak mały, jak to tylko możliwe (aby uniknąć wyłączenia go gdzieś, gdzie jest użyteczny) i zawsze towarzyszyć wyłączeniu z komentarzem, dlaczego wyłączasz, np. '// istnieje dla interop' w tym przypadku. –

+0

Dobra rada @Jon, z całego serca się zgadzam. –

4

Otrzymałem VS, aby wygenerować szkielet implementacji dla System.ComponentModel.INotifyPropertyChanged, a zdarzenia zostały zaimplementowane jako pola, które spowodowały ostrzeżenia CS0067.

Alternatywnie do rozwiązania podanego w zaakceptowanej odpowiedzi Przekształciłem pola w właściwości i ostrzeżenie zniknęło.

Ma to sens, ponieważ cukier składniowy deklaracji właściwości jest wkompilowany w pole plus metody pobierające i/lub ustawiające (dodaj/usuń w moim przypadku), które odnoszą się do tego pola. Ten spełnia kompilator i ostrzeżenia nie są podniesione:

struct HTTP_FILTER_PREPROC_HEADERS 
{ 
    // 
    // For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value. 
    // Header names should include the trailing ':'. The special values 
    // 'method', 'url' and 'version' can be used to retrieve the individual 
    // portions of the request line 
    // 

    internal GetHeaderDelegate GetHeader {get;set;} 
    internal SetHeaderDelegate SetHeader { get; set; } 
    internal AddHeaderDelegate AddHeader { get; set; } 

    UInt32 HttpStatus { get; set; }    // New in 4.0, status for SEND_RESPONSE 
    UInt32 dwReserved { get; set; }    // New in 4.0 
} 
+0

Twoje rozwiązanie jest o wiele bardziej wdzięczne niż wyłączenie ostrzeżenia, ale może zakłócać niektóre atrybuty tylko w terenie, np. MarshalAsAttribute. – HuBeZa

+0

Info: Rzeczywiste prywatne pola wygenerowane w tej sytuacji mogą mieć "dziwne" nazwy, takie jak ' k__BackingField', w zależności od szczegółów implementacji używanego kompilatora C#. –

11

Innym „rozwiązanie”, aby rozwiązać te ostrzeżenia jest uzależniając struct public. Ostrzeżenia nie są wtedy wydawane, ponieważ kompilator nie może wiedzieć, czy pola są używane (przypisane) poza złożeniem.

Mimo to elementy "interop" zwykle nie powinny być publicznie dostępne, lecz powinny być oznaczone jako internal lub private.

+0

Miło, to ukrywa ostrzeżenie ... ale ustawienie takiej "struktury" jako "publicznej" jest bardziej prawdopodobne, niż błąd, który próbujemy maskować. (Prawdopodobnie nie powinieneś niepotrzebnie eksponować typów używanych do wewnętrznej implementacji, a typy z polami publicznymi prawdopodobnie nie należą do publicznego API). Tylko po to, by wzmocnić twoją radę, że takie typy powinny być "raczej" wewnętrzne "lub" prywatne ";-). – binki

1

Użytkownicy C/C++ mają (void)var; tłumić nieużywane ostrzeżenia zmiennych. Właśnie odkryłem można też tłumić nieużywanych zmiennych ostrzeżenia w C# z operatorami bitowe:

 uint test1 = 12345; 
     test1 |= 0; // test1 is still 12345 

     bool test2 = true; 
     test2 &= false; // test2 is now false 

Oba wyrażenia nie produkują nieużywanych zmiennych ostrzeżeń w VS2010 C# 4.0 i Mono 2.10 kompilatory.

+2

Działa dla 'uint', ale nie dla innych typów, jako' wyjątek'. Czy znasz ogólny trik równoważny C/C++ 'var;'? – manuell

Powiązane problemy