Declaración simple de C#Noop
(14)
¿Qué es una simple declaración Noop en C #, que no requiere implementar un método? (Sin embargo, los métodos Inline / Lambda están bien).
Mi caso de uso actual: quiero ocupar el bloque de captura de un try-catch, por lo que puedo entrar en él mientras depuro e inspeccionar la excepción.
Soy consciente de que probablemente debería manejar / registrar la excepción de todos modos, pero ese no es el punto de este ejercicio.
La operación estándar vacía de declaración / noop en C # es
;
como enif (true) ;
.
- blueberryfields
Pero usando ese estándar ;
como una rama de una declaración if
, MS Visual Studio 2010 muestra una advertencia: "Posible declaración vacía errónea". (Advertencia CS0642, aunque VS2010 no me dice eso o enlace a la ayuda real para la advertencia).
Peor aún, la especificación de lenguaje C # de MSDN no menciona que en realidad la codificación de esa declaración vacía como una rama de una instrucción if
provoque la advertencia CS0642 "Posible declaración vacía errónea". (Advertencia porque es "mala forma", potencialmente ambigua.)
Peor aún, parece que VS2010 no ofrece ninguna manera de suprimir NEATLY una advertencia individual. Tendría que insertar #pragma warning disable CS0642
antes de las líneas y [opcionalmente] #pragma warning disable CS0642
después. Para mí, esto es más feo que la advertencia. Estaría mejor usando { }
en lugar de ;
. (Podría usar un reemplazo que sea un poco menos feo).
Busqué aquí un "C # no-op" porque quería una alternativa a la "declaración vacía", para deshacerme de esa advertencia. No necesito un puesto de control. Solo quiero un do- [absolutamente] -nada que no sea ambigua como "la declaración vacía".
La alternativa no debe provocar alguna otra advertencia. int u;
no es bueno porque provoca una advertencia "La variable ''u'' se declara pero nunca se usa". int u = 0;
no es bueno porque provoca una advertencia "La variable ''u'' está asignada pero su valor nunca se usa".
Si noop;
(o similar) se agregaron como una declaración vacía no ambigua (NO una definición de macro), eso sería genial.
Si noop();
(o similar) era una función con un cuerpo vacío (que puede desaparecer completamente cuando el compilador lo alinea), que sería casi genial.
Cuando la rama es solo una declaración, a menudo omito las {
y }
LÍNEAS circundantes porque no son necesarias y extienden el código verticalmente, lo que dificulta su lectura. La inconsistencia en el lenguaje es que no puedo omitir las LÍNEAS {
y }
circundantes cuando rodean las declaraciones CERO. Puedo compactar las dos líneas a { }
en la misma línea, pero eso es inconsistente. Yo pienso en una línea es la mejor solución, y NO debe causar una advertencia en el sentido [no declarado] de "forma incorrecta". Creo que la advertencia CS0642 debería haberse desactivado. Creo que el siguiente código debería ser aceptable como está:
if (condition1)
action1;
else if (condition2)
; // (do nothing)
else if (condition3)
action3;
else if (condition4)
; // (do nothing)
else if (condition5)
action5;
else
action99;
(Lamenté no poder escribir esto como un comentario porque aún no tenía "reputación de 50 para comentar". Ahora que puedo comentar, a 2K bytes, es demasiado largo para un comentario de 1.5K bytes, así que me quedo aquí. .)
¿Está intentando depurar una versión de lanzamiento (optimizada)? Normalmente es el optimizador el que elimina las variables sin referencia y los bloques vacíos.
Dos soluciones:
- Depurar en una construcción de depuración.
- Coloque un punto de ruptura en la
catch
sí y use$exception
, creada por el depurador para hacer referencia a la excepción en vuelo, en la ventana de herramientas Locales.
¿Por qué sobre-diseñar esto?
var x = 0;
funciona bien :)
Además de las respuestas que responden directamente a la pregunta.
Si solo desea romper, siempre puede poner el punto de interrupción en la apertura {
o cierre }
del bloque catch
.
Bueno, el NOP en C # existe, como en C y es '';''
y su definición correcta es " la declaración vacía ", pero para el uso que pretende, es suficiente para poner el punto de interrupción en el corchete de cierre de cierre ... No es necesario mantener la alerta viva, ya que la vida útil de una referencia de objeto en un El método se extiende hasta el final del método cuando se adjunta el depurador. Así que simplemente necesitas escribir
catch(Exception exception)
{
}
y coloque el punto de interrupción en el corchete de cierre y vea el contenido de la excepción.
La instrucción estándar vacía / noop en c # es
;
como en:
if (true)
;
esto aborda específicamente su caso de uso (solo coloque un punto de quiebre en la línea; o, de lo contrario, camine hacia él), es mínimo y el entorno lo respalda directamente para este propósito (de modo que incluso si está haciendo cosas complejas) , como mirar a la fuente compilada, no tendrá ningún ruido adicional / etc .. para preocuparse por el compilador / optimizador / etc ...) - y tiene la ventaja adicional de poner una advertencia, como un recordatorio para elimínelo de su código cuando haya terminado de depurar / empujar a producción
Me gusta esto, solo porque confundirá a quienquiera que lo encuentre:
catch (SomeException e)
{
lock(e);
}
Puedes escribir una función que no haga nada.
public static void Noop()
{
}
Qué tal si:
GC.KeepAlive(e);
donde e
es la variable de excepción?
(No he intentado poner un punto de ruptura en la declaración de captura en sí. Parece que deberías poder hacerlo, precisamente por esta razón. Pero funciona o no es un asunto diferente).
O algo más críptico, asumiendo que ya tiene una directiva de uso para System.LINQ
:
"".AsEnumerable();
Sé que esta es una pregunta antigua y, técnicamente, esta respuesta no se relaciona con el caso de uso del autor de la pregunta. Sin embargo, hay una instrucción NOOP en CIL, que es nop
. Como experimento, tome la siguiente aplicación CIL.
.assembly extern mscorlib {}
.assembly Test
{
.ver 1:0:1:0
}
.module test.exe
.method static void main() cil managed
{
.maxstack 1
.entrypoint
nop
nop
nop
nop
ret
}
Si compila la aplicación y la descompila con una herramienta como ILSpy, a C #, este es el contenido del método main ():
static void main()
{
}
Como puedes ver, no hay nada allí. Sin embargo, si queremos verificar que el compilador CIL no optimizó estas declaraciones nop
, podemos ver nuestra aplicación en el código IL descompilado en ILSpy, y esto es lo que vemos para el método principal:
.method static privatescope
void main$PST06000001 () cil managed
{
// Method begins at RVA 0x2050
// Code size 5 (0x5)
.maxstack 1
.entrypoint
IL_0000: nop
IL_0001: nop
IL_0002: nop
IL_0003: nop
IL_0004: ret
} // end of method ''<Module>''::main
CIL ciertamente está compilando las instrucciones nop
en el ensamblaje. Como C # no tiene implementación de esta instrucción, estos nop
no se muestran dentro del código de C # desensamblado.
No tengo una licencia para Reflector, pero imagino que si descompila estos binarios con Reflector obtendría una salida similar para C #.
Si quiere entrar en el método, podría codificar un punto de interrupción:
System.Diagnostics.Debugger.Break();
Alternativamente, si no compila en el modo de lanzamiento, la siguiente línea emitirá IL que puede interrumpir:
var a = 1;
También puede escribir un Debug.Break () que sea específico para su máquina:
[Conditional("DEBUG")]
[Obsolete("Please remove me before checkin.")]
public static void Break()
{
#IF DEBUG
if (Dns.GetHostName() == "PROTECTORONE")
Debugger.Break();
#ENDIF
}
Tenga en cuenta que debido a [Conditional("DEBUG")]
ese método no será llamado en los sitios de llamadas durante una compilación RELEASE.
Si realmente quieres noop, entonces esto define una acción sin nombre que no hace nada, y luego la invoca, causando que nada suceda:
((Action)(() => { }))();
Solución confiable
try
{
blablablablaStatemnt();
}
catch(Exception ex)
{
#IF DEBUG
Debugger.Break();
#END IF
}
¡Tan simple como esto!
De otra manera
puntos de ruptura
puede ser muy útil;
Usted puede simplemente escribir:
catch {
;
}
La declaración vacía con un solo punto y coma es el C # NOOP.