remarks example cref c# using finally expansion try-catch

example - Curioso C#usando la expansión de la declaración



remarks c# (4)

He ejecutado ildasm para encontrar que esto:

using(Simple simp = new Simple()) { Console.WriteLine("here"); }

genera un código IL que es equivalente a esto:

Simple simp = new Simple(); try { Console.WriteLine("here"); } finally { if(simp != null) { simp.Dispose(); } }

y la pregunta es ¿por qué demonios se comprueba nulo en el final? El bloque finally solo se ejecutará si se ejecuta el bloque try, y el bloque try solo se ejecutará si el constructor Simple tiene éxito (es decir, no lanza una excepción), en cuyo caso simp no será nulo. (Si existe el temor de que algunos pasos intermedios se interpongan entre el constructor Simple y el comienzo del bloque try, entonces eso sería realmente un problema porque entonces podría lanzarse una excepción que evitaría que el bloque finally se ejecute). Entonces, ¿por qué diablos?

Dejando a un lado (por favor) el argumento de si la declaración de uso es mejor que intentar-finalmente, escribo mis bloques de intentar-finalmente como:

Simple simp = new Simple(); try { Console.WriteLine("here"); } finally { simp.Dispose(); simp = null; // sanity-check in case I touch simp again // because I don''t rely on all classes // necessarily throwing // ObjectDisposedException }


No, el bloque finally SIEMPRE será ejecutado. Es posible que no obtenga el objeto de una función nueva, sino de otra que devuelva su objeto, y podría devolver NULL. usando () es tu amigo!

dss539 tuvo la amabilidad de sugerir que incluyera su nota:

using(Simple simp = null)

Es otra razón por la que la expansión debe verificar primero si hay null.


Parece que tu comentario:

"Si existe el temor de que algunos pasos intermedios se interpongan entre el constructor Simple y el comienzo del bloque try, entonces eso sería realmente un problema porque entonces podría lanzarse una excepción que evitaría que el bloque finally se ejecute".

es posiblemente muerto en. Ver:

Atomicidad y fallas asíncronas de excepción

También quiero anotar los problemas con WCF y usando:

Evitar problemas con la declaración de uso y los servidores proxy del servicio WCF que hace referencia a:

Evitar problemas con la declaración de uso


MSDN en la declaración de uso.

Lo que creo que es extraño es que no se expande a:

Simple simp = new Simple(); Simple __compilergeneratedtmpname = simp; try { Console.WriteLine("here"); } finally { if(__compilergeneratedtmpname != null) { __compilergeneratedtmpname.Dispose(); } }


using(Simple simp = null) es otra razón más por la que la expansión debe verificar primero el valor nulo.