2010-09-29 26 views
92

Tengo un archivo HTTPSystemDefinitions.cs en el proyecto C# que básicamente describe el ISAPI de Windows anterior para el consumo del código administrado.Suprimir "nunca se usa" y "nunca se asigna a" advertencias en C#

Esto incluye el conjunto completo de Estructuras relevantes para el ISAPI no todas o que son consumidas por el código. En la compilación de todos los miembros de campo de estas estructuras están causando una advertencia como la siguiente: -

Warning 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.SetHeader' El campo no está asignado a, y siempre tendrá su nulo valor predeterminado

o

Advertencia El campo 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.HttpStatus' nunca se utiliza

¿Se pueden deshabilitar con #pragma warning disable? Si es así, ¿cuáles serían los números de error correspondientes? Si no, ¿hay algo más que pueda hacer? Tenga en cuenta que solo tengo que hacer esto para este archivo, es importante que vea advertencias como estas provenientes de otros archivos.

Editar

Ejemplo struct: -

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

¿Puede mostrar la declaración de esos campos, o más bien, la estructura en la que se encuentran? es decir. dar un ejemplo. –

+0

@Lasse: Ejemplo agregado. – AnthonyWJones

+8

Si se trata de definiciones de interoperabilidad, normalmente pondría '[StructLayout (LayoutKind.Sequential)]' para asegurarse de que el diseño de la memoria sea correcto (en la implementación actual estará incluso sin este atributo, pero AFAIK no está garantizado)) Si recuerdo correctamente, el compilador de C# detecta la presencia de este atributo y automáticamente suprime esas advertencias, ya que sabe que los campos deben estar ahí para la interoperabilidad. (Podría estar equivocado al respecto, por lo tanto publicar como un comentario en lugar de una respuesta). –

Respuesta

164

Sí, estos pueden ser suprimidas.

Normalmente, me opongo a la supresión de advertencias, pero en este caso, las estructuras utilizadas para la interoperabilidad requieren absolutamente algunos campos para estar presentes, aunque nunca tenga la intención de (o puede) usarlos, así que en este caso creo debe estar justificado.

Normalmente, para suprimir esas dos advertencias, debe corregir el código ofensivo. El primero ("... nunca se usa") suele ser un olor a código de las sobras de versiones anteriores del código. Tal vez el código fue eliminado, pero los campos quedaron atrás.

El segundo es generalmente un olor de código para los campos incorrectamente utilizados. Por ejemplo, puede escribir incorrectamente el nuevo valor de una propiedad a la propiedad misma, nunca escribiendo en el campo de respaldo.


Para suprimir las advertencias de "campo XYZ nunca se utiliza", que hacer esto:

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

Para suprimir las advertencias para "campo XYZ no está asignado a, y siempre tendrá su valor predeterminado XX", esto se hace:

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

para encontrar un número tan alerta a sí mismo (es decir.¿Cómo supe utilizar 0169 y 0649), esto se hace:

  • compilar el código como normal, esto añadirá algunas advertencias a su lista de errores en Visual Studio
  • Cambiar a la ventana de resultados, y la construir la salida, y la caza de las mismas advertencias
  • copiar el código de advertencia de 4 dígitos del mensaje relevante, que debe tener este aspecto:

    C: \ Dev \ VS.NET \ ConsoleApplication19 \ ConsoleApplication19 \ Program.cs (10,28): advertencia CS : Campo 'ConsoleApplication19.Program.dwReserved' nunca es asignado, y siempre tendrá su valor por defecto 0


Advertencia: De acuerdo con el comentario de @Jon Hanna, tal vez algunas advertencias están en orden para esto, para futuros buscadores de esta pregunta y respuesta.

  • En primer lugar, y sobre todo, el acto de suprimir una advertencia es similar a tragar pastillas para el dolor de cabeza. Claro, podría ser lo correcto a veces, pero no es una solución general. A veces, un dolor de cabeza es un síntoma real que no debe enmascararse, lo mismo con las advertencias. Siempre es mejor intentar tratar las advertencias fijando su causa, en lugar de simplemente eliminarlas ciegamente de la salida de compilación.
  • Habiendo dicho eso, si necesita suprimir una advertencia, siga el patrón que expuse arriba. La primera línea de código, #pragma warning disable XYZK, deshabilita la advertencia para el resto de ese archivo, o al menos hasta que se encuentre el correspondiente #pragma warning restore XYZK. Minimice la cantidad de líneas en las que deshabilita estas advertencias. El patrón anterior desactiva la advertencia para una sola línea.
  • Además, como menciona Jon, es una buena idea comentar por qué estás haciendo esto. Desactivar una advertencia es definitivamente un olor a código cuando se realiza sin una causa, y un comentario evitará que los futuros mantenedores pasen tiempo preguntándose por qué lo hiciste o incluso quitándolo e intentando corregir las advertencias.
+0

¡Esto es genial! –

+8

Recomendaría más a la respuesta anterior, que el alcance de la desactivación sea lo más pequeño posible (para evitar deshabilitarlo en algún lugar donde sea útil) y acompañar siempre una desactivación con un comentario de por qué está deshabilitando, p. '// existe para la interoperabilidad 'en este caso. –

+0

Ese es un buen consejo @Jon, estoy totalmente de acuerdo. –

4

Obtuve VS para generar el esqueleto de implementación para System.ComponentModel.INotifyPropertyChanged y los eventos se implementaron como campos que activaron las advertencias de CS0067.

Como alternativa a la solución dada en la respuesta aceptada Convertí los campos en propiedades y la advertencia desapareció.

Esto tiene sentido ya que las declaraciones de propiedades sintaxis azúcar se compilan en un campo más métodos getter y/o setter (agregar/eliminar en mi caso) que hacen referencia al campo. Esto satisface el compilador y las advertencias no resucitan:

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

Su solución es mucho más elegante que inhabilitar la advertencia, pero puede interferir con algunos atributos de solo campo, p. MarshalAsAttribute. – HuBeZa

+0

Información: Los campos privados reales generados en esta situación pueden tener nombres "extraños" como ' k__BackingField', según los detalles de implementación del compilador C# utilizado. –

11

Otra "solución" para fijar estas advertencias es haciendo que la estructura public. Las advertencias no se emiten porque el compilador no puede saber si los campos se están utilizando (asignados) fuera del ensamblaje.

Dicho esto, los componentes "interoperativos" generalmente no deberían ser públicos, sino más bien internal o private.

+0

Bueno, esto oculta la advertencia ... pero establecer una 'struct' como' public' es más probable que sea un error que la advertencia que intentamos enmascarar. (Probablemente no deba exponer innecesariamente los tipos utilizados para la implementación interna y los tipos con campos públicos probablemente no pertenezcan a una API pública). Solo para reforzar su consejo de que tales tipos deberían ser "más bien 'internos' o 'privados'" ;-). – binki

1

Los usuarios de C/C++ tienen (void)var; para suprimir las advertencias de variables no utilizadas. acabo de descubrir que también puede suprimir las advertencias de las variables utilizadas en C# con operadores de bits:

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

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

Ambas expresiones no producen advertencias variables utilizadas en VS2010 C# 4.0 y 2.10 Mono compiladores.

+2

Funciona para 'uint', pero no para otros tipos, como' Exception'. ¿Conoces un truco genérico equivalente al C/C++ 'var;'? – manuell

Cuestiones relacionadas