La especificación para el compilador define the behaviour of lock like so:
El tipo de tiempo de compilación de la expresión de una sentencia de bloqueo será un tipo de referencia o un parámetro> (§25.1.1) que se sabe que es un tipo de referencia. Es un error en tiempo de compilación para el tipo de tiempo de compilación de la expresión para denotar un tipo de valor.
Luego define lo que es equivalente a siempre que compila
Desde Monitor.Salir es solo una llamada a un método sin ninguna restricción, no impedirá que el compilador pegue automáticamente el int y siga su camino feliz (y muy) equivocado.
lock
no es simplemente azúcar sintáctica de la misma manera foreach
no es simplemente azúcar sintáctica. La transformación IL resultante es no presentada al resto del código como si fuera lo que se había escrito.
En foreach
es ilegal modificar la variable de iteración (a pesar de que no haya nada en el nivel de IL en el código de salida resultante que podría evitar esto). En el bloqueo, el compilador evita los tipos de valores conocidos de tiempo de compilación, nuevamente a pesar de que IL no se preocupa por esto.
Como acotación al margen:
En teoría, el compilador podría 'bendecido' con el conocimiento íntimo de este (y otros) los métodos para que se descubrió casos obvios de que esto ocurra, pero fundamentalmente es imposible al punto de siempre esto en tiempo de compilación (considere un objeto pasado desde otro método, ensamblado o mediante reflexión) por lo que molestarse en detectar cualquiera de estos casos probablemente sea contraproducente.
Cuanto más sepa el compilador sobre las funciones internas de la API, más problemas tendrá si desea modificar la API en el futuro.
Es posible, por ejemplo, que se pueda agregar una sobrecarga de Monitor.Enter() que tomó un int y bloqueado en un mutex de ancho de proceso asociado con el valor int.
Esto se ajustaría a las especificaciones del monitor (aunque probablemente sería espantoso) pero causaría problemas masivos para el compilador anterior que todavía evitaba alegremente una operación que se había vuelto legal.
No creo que haya ninguna comprobación. No se ha expandido el bloqueo con un Monito.Ingrese en un bloque try y Monitor.Exit en el bloque finally. – Sandbox
no, se amplía a eso, pero primero el compilador detecta si estás siendo tonto en el camino ... – ShuggyCoUk