Ho appena finito di ramazzare un po di codice in cui veniva pesantemente usata la clause "Using" di C#. Per chi non lo sapesse in pratica è un "sintactic sugar" che non fa altro che incapsulare dentro un try...catch...finally la variabile usata dentro lo using.
Quindi un costrutto del tipo
using(SqlConnection cn = new SqlConnection()) {..}
catch {...}
è equivalente a
SqlConnection cn;
try {
cn=new SqlConnection();
}
catch {...}
finally {
in(null!=cn)
cn.Dispose();
}
Il risultato è che il codice è più compatto, dal punto di vista dell'IL generato non cambia nulla.
Cambia però, a mio avviso, la mantenibilità del codice, perchè quella che era partito come un codice semplice nel giro di poche modifiche è diventato quello che segue
using(SqlConnection cn = new SqlConnection()) {
SqlCommand cm = cn.CreateCommand();
SqlTransaction tn = cn.BeginTransaction();
cm.Transaction = tn;
}
catch {...}
In pratica quindi mi ritrovo ad aver generato 2 nuove variabili (di oggetti che implementano la IDisposable) e di cui nessuno farà mai la dispose. Quindi o rimuovo la Using mettendo una try...catch...finally oppure (se, come nel caso in questione, in codice è stato fatto da una persona poco esperta) me lo scordo. Non dico che con la finally scritta in modo esplicito tutti poi si ricordano di fare la Dispose di tutto, ma se lo vedi scritto in maniera esplicita magari il dubbio ti viene...
Con tutto questo cosa voglio dire???? Nulla, ma i fatti mi cosano. E la Using è male. Ed in generale mettere in un linguaggio dei costrutti che non siano altro che "sintactic sugar" probabilmente è altettanto un male.
[Edit]
Un commento veloce sul discorso di indentare gli using. Scusa ma (è un parere personale) sto codice non mi piace:
using (SqlConnection cn = new SqlConnection()) {
using (SqlCommand cm = cn.CreateCommand()) {
using(SqlTransaction tn = cn.BeginTransaction ()) {
...
}
}
}
Ma ripeto, è un parere personale. Tecnicamente il problema può essere che implicitamente crea un "catch stack" abbastanza profondo, quindi nel momento in cui hai un'eccezione nello strato interno questa deve navigare 3 catch per risalire.
Sugli altri sono abbastanza d'accordo, se il programmatore zuccone non mi fa le Dispose si incasina in un modo e nell'altro, l'unica cosa è che se il codice è esplicito magari gli viene in mente di capire perchè esiste quella Dispose in fondo e magari si istruisce...