"Tratar todas las advertencias como errores excepto ..." en Visual Studio

124

En Visual Studio, puedo seleccionar la opción "Tratar advertencias como errores" para evitar que mi código se compile si hay advertencias. Nuestro equipo usa esta opción, pero hay dos advertencias que nos gustaría mantener como advertencias.

Hay una opción para suprimir las advertencias, pero QUEREMOS que aparezcan como advertencias, para que eso no funcione.

Parece que la única forma de obtener el comportamiento que queremos es ingresar una lista de cada número de advertencia de C # en el cuadro de texto "Advertencias específicas", excepto los dos que queremos que sean tratados como advertencias.

Además del dolor de cabeza de mantenimiento, la mayor desventaja de este enfoque es que algunas advertencias no tienen números, por lo que no se pueden hacer referencia explícitamente. Por ejemplo, "No se pudo resolver esta referencia. No se pudo ubicar el ensamblado 'Datos ...'"

¿Alguien sabe de una mejor manera de hacer esto?


Aclarando para aquellos que no ven de inmediato por qué esto es útil. Piense en cómo funcionan la mayoría de las advertencias. Te dicen que algo está un poco fuera del código que acabas de escribir. Tarda unos 10 segundos en solucionarlos, y eso mantiene el código base más limpio.

La advertencia "Obsoleto" es muy diferente de esto. A veces arreglarlo significa simplemente consumir una nueva firma de método. Pero si una clase entera es obsoleta y su uso está disperso a través de cientos de miles de líneas de código, podría tomar semanas o más solucionarlo. No desea que la compilación se rompa durante tanto tiempo, pero definitivamente desea ver una advertencia al respecto. Este no es solo un caso hipotético, esto nos ha sucedido.

Las advertencias literales de "advertencia" también son únicas. A menudo quiero registrarlo, pero no quiero romper la compilación.

Neil
fuente
¿Puedes poner espacios en tu gran lista de números? Se ha rellenado la línea de envoltura.
Ray
Dios mío, odio las complicadas reglas que componen las personas, a menudo para calmar el ego de una persona específica.
Jon Limjap
21
Veo su punto sobre la advertencia obsoleta, esto no es arbitrario.
Ed S.
En mi experiencia, permitir incluso una advertencia en su compilación es como agregar una primera asíncrona / espera. Pronto habrá decenas de ellos. En todas las configuraciones, recuerdo que un desarrollador puede ver menos de 10 advertencias en la ventana Lista de errores en VS. Puedo apostar que tan pronto como tenga más de 5 advertencias, la gran mayoría de los desarrolladores en un equipo no podrán detectar uno nuevo; en su configuración, significa que no detectarán la advertencia de que el método es obsoleto, lo que desafía todo el propósito de tener una advertencia :) ¿Cuál es su experiencia con este Neil?
tymtam
@mayu, es un enigma. Muchas veces, he visto advertencias ignoradas durante mucho tiempo. Pero al final, o muestra la advertencia o no muestra nada en absoluto. Si está mostrando la advertencia, al menos existe la posibilidad de que alguien aprenda algo útil de ella. Si trata la mayoría de las advertencias como errores, entonces las pocas que quedan pueden llamar más la atención.
Neil

Respuestas:

155

Puede agregar una WarningsNotAsErrorsetiqueta en el archivo del proyecto.

<PropertyGroup>
    ...
    ...
    <WarningsNotAsErrors>618,1030,1701,1702</WarningsNotAsErrors>
</PropertyGroup>

Nota: 612y 618ambas son advertencias sobre Obsoleto, no sé la diferencia, pero el proyecto en el que estoy trabajando informa Obsolete con la advertencia 618.

SvenL
fuente
24
La diferencia entre 612 y 618 es el comentario de ObsoleteAttribute. Un atributo obsoleto sin comentario genera el error 612, y uno con un comentario genera 618.
Marco Spatz
@MarcoSpatz Exactamente. Entonces podemos tratar a los [Obsolete]miembros donde messageestá nullcomo errores, mientras permitimos que aquellos donde messageestá configurado permanezcan solo como advertencias. Si el errorparámetro se establece trueen ObsoleteAttribute, se genera un CS0619 en su lugar. Esto parece no funcionar si messagees así null(¿pero quién lo haría de [Obsolete(null, true)]todos modos?).
Jeppe Stig Nielsen
Para F #, --warnaserror-:618,1030úselo en el campo Build-> Other flags. Esta opción de proyecto aún no está implementada para proyectos F #. github.com/Microsoft/visualfsharp/issues/3395
Asik
2
Es bueno saber que existe "WarningsNotAsErrors". Debería estar disponible en la configuración del proyecto sin editar manualmente el archivo. Gracias.
AFract
1
Microsoft realmente arruinó esto (y 11 años después, ¡no ha arreglado las cosas!). La configuración del proyecto cambia <NoWarn>, que es inferior en la mayoría de los casos y no se pudo poner <WarningsNotAsErrors>en la interfaz de usuario. Prestigio.
usuario2864740
13

/ warnaserror / warnaserror-: 618


fuente
1
Gracias por su aporte. Aunque no resuelven el problema IDE, estos son los comentarios más útiles hasta ahora.
Neil
2
¿Dónde agregas esto?
checho
@checho, esos interruptores se agregarían en la línea de comando al llamar a msbuild. Para nuestros propósitos, la respuesta principal es más útil, porque podemos incluirla en el proyecto en lugar de tener que modificar la forma en que llamamos msbuild.
Neil
No funciona con MSBuild 15.9.21 + g9802d43bc3: MSBUILD : error MSB1001: Unknown switch. Switch: /warnaserror-:618
Paul B.
3

o más específicamente, en su caso:

/ warnaserror / warnaserror-: 612,1030,1701,1702

esto debería tratar todas las advertencias como errores, excepto las que están en su lista separada por comas


fuente
1

¿Por qué quieres seguir viendo advertencias que no estás tratando como errores? Estoy confundido acerca de por qué esto es deseable, ya sea que los arregles o no.

¿Funcionarían dos archivos de compilación / solución diferentes, o un script para copiar uno y luego modificar el nivel de advertencia / advertencia? Parece que quizás quieras que algunas ejecuciones del compilador graznen, pero otras que quieras seguir.

Por lo tanto, diferentes compiladores parecen ser un buen camino a seguir. Puede hacer esto con diferentes objetivos: uno etiquetado como depuración o liberación y los otros etiquetados adecuadamente sobre las advertencias.

Tim
fuente
77
La mayoría de las advertencias se producen debido a una simple confusión en mi código (por ejemplo, he declarado una variable que no uso). Una advertencia obsoleta a menudo ocurre debido a un cambio en el código de otra persona. Arreglar esto podría llevar semanas de desarrollo. #warning es una advertencia que quiero en el código (probablemente una solución a largo plazo).
Neil
44
En otras palabras, hay advertencias de que no quiero romper mi compilación. Si #warning rompe la construcción, entonces no puedo registrar una. Si Obsolete rompe la construcción, entonces otro equipo del que dependemos podría romper la construcción de nuestro equipo sin saberlo simplemente agregando un atributo obsoleto.
Neil
@Neil Estoy de acuerdo con algunos de tus argumentos, pero eliminar una var que no usas no lleva mucho tiempo Y definitivamente quieres saber que otro equipo hizo algo obsoleto.
tymtam
@mayu, gracias por tu comentario. Estoy de acuerdo con una var que no usas. Es por eso que quiero que el compilador lo trate como un error. También estoy de acuerdo en que quieres saber cuándo algo está obsoleto. Pero si lleva mucho tiempo refactorizar algo obsoleto de nuestro código, sus opciones son 1) Tratar esta advertencia como una advertencia 2) Dejar que su compilación permanezca rota durante mucho tiempo 3) Otra solución como desactivar las advertencias como errores. Con la mayoría de las advertencias como errores, es probable que su lista de advertencias se mantenga corta, por lo que es más probable que note cuándo aparecen. ¿Cuál es tu solución preferida?
Neil
1
@mayu, otro equipo (ya sea dentro de la misma compañía o fuera de ella) puede legítimamente comunicar que una clase, método u otro componente se está eliminando gradualmente durante un período de tiempo. Agregar un atributo es una buena manera de señalar esto a los consumidores de una biblioteca. No me parece problemático hacer esto. De hecho, agregar el atributo lo antes posible es una buena manera de asegurarse de que otros estén al tanto de los cambios futuros.
Neil
1

Estoy usando tratar advertencias como errores.

En casos excepcionales, cuando aparece una advertencia aceptable (es decir, que hace referencia a un miembro obsoleto o falta documentación en las clases de serialización XML), debe suprimirse explícitamente con #pragma disable (y, opcionalmente, podría proporcionarse una razón para no tener un código limpio) como un comentario a lo largo)

La presencia de esta directiva también permite averiguar quién aceptó esta violación de advertencia (por acción de "culpa" del control de versiones) en caso de que haya algunas preguntas.

Rinat Abdullin
fuente
3
También uso esto, aunque no resuelve los problemas mencionados en mi descripción. Quiero ciertas advertencias tratadas como advertencias, no ocultas.
Neil
0

¿Por qué no simplemente tener una regla que diga "Quien ingrese el código con cualquier advertencia dentro de él que no sea 612, 1030, 1701 o 1702 debe ir a la pizarra y escribir cien veces" No volveré a ingresar el código con advertencias rechazadas nuevamente. '"

erikkallen
fuente
9
Buena suerte para hacer cumplir eso ... ¡Tratar las advertencias como errores es un paso muy importante para aumentar la calidad general del código y obligará a los desarrolladores a corregir su código! Toda la automatización del granizo, el trabajo manual es tan del siglo XX: ¡ish!
Andreas Magnusson el
@AndreasMagnusson Si solo la falta de advertencias garantizara la calidad del código ..
user2864740
2
@ user2864740: De acuerdo, no hay balas de plata. Pero es una falacia muy común rechazar algo útil bajo la premisa de que no es una bala de plata.
Andreas Magnusson
-4

Me parece que el problema raíz es realmente una combinación de sus advertencias de tratamiento como errores, cuando claramente no lo son, y su política aparente de permitir registros que violen esto. Como usted dice, desea poder seguir trabajando a pesar de una advertencia. Solo ha mencionado algunas advertencias que desea poder ignorar, pero ¿qué pasa si alguien más en el equipo causó algún otro tipo de advertencia, que le tomaría igual de tiempo para solucionarlo? ¿No te gustaría poder ignorar eso también?

La solución lógica sería: 1) No permitir registros si el código no se compila (lo que significa que quienes crearon las advertencias tendrán que corregirlos, ya que en realidad, rompieron la compilación), o 2) tratar las advertencias como advertencias. Cree dos configuraciones de compilación, una que trate las advertencias como errores, que se pueden ejecutar regularmente para garantizar que el código no tenga advertencias, y otra, que solo las trata como advertencias, y le permite trabajar incluso si alguien más introdujo una advertencia.

jalf
fuente
1
Usando la respuesta seleccionada, es fácil agregar a la lista de advertencias tratadas como advertencias. Eso funciona mucho mejor que cualquiera de las soluciones propuestas. Las advertencias claramente no son errores, pero tratar la mayoría de las advertencias como errores significa que el código nunca se registrará con esas advertencias.
Neil