C# using-Anweisung

20k Zeilen langer Code? mit 30 Personen? Ich habe Alleine einen Projekt mit min 30k Zeilen geschrieben. Natürlich 1/5 Verhältinis Kommentar (1 Zeile) und (4 Zeilen) Code.

Nagut, zurück zum Thema... Using ist nur dann sinnvoll wenn von deinen Codeabschnitt erwartet wird, dass es eine Exception werfen kann. Wenn IO sehr wichtig sein sollte und alle Exception richtig behandelt werden sollten, sollte man USING vermeiden, da USING try catch finally ausführt, wobei, im finally der dispose vom Object aufgerufen wird (ACHTUNG, using kann nur mit DISPOSABLE Objekten zusammenarbeiten).

habe jetzt nicht alle beiträge durchgelesen habe, aber ich wollte zum USING unbedingt auch was sagen!
 
Wie kommst du drauf, dass man using nur Verwendet, wenn der Codeabschnitt eine Exception werfen kann? Mit Exceptions hat das eigentlich erst mal nichts zu tun.
Using ist vor allem dafür da, dass auf die in der Klammer angegebenen Objekte nach verlassen des using-Blocks implizit dispose() aufgerufen wird, um direkt Ressourcen frei zu geben. Von daher ist es auch völlig logisch, dass man using nur auf Objekte anwenden kann, welche IDisposable implementieren.

Beispiel

using (Font font1 = new Font("Arial", 10.0f))
{
//...
}


Nach verlassen des Blocks hast du ein implizites font1.dispose(), ohne es hinschreiben zu müssen. Genau dafür ist using gedacht. Das Beispiel ist übrigens aus dem msdn, wobei Font garkeine Exceptions wirft.. keine Ahnung wie du da au Exceptionhandling kommst.
 
Das was das using statement da im Grunde verkörpert, ist auch unter dem Begriff RAII (vor allem in C++) bekannt und ist für 'exception-safe programming' von unschätzbarem Wert. Völlig unbegründet ist die Verbindung zum Exception-handling also nicht.

Allerdings ist RAII natürlich auch ohne Exceptions genau so nützlich.
Ergänzung ()

roker002 schrieb:
Wenn IO sehr wichtig sein sollte und alle Exception richtig behandelt werden sollten, sollte man USING vermeiden, da USING try catch finally ausführt [...]

Der hervorgehobene Teil macht mir Sorgen. Ich bin nicht gerade ein C#-Kenner; deshalb möchte ich da mal nachhaken. Deine Aussage impliziert für mich, daß ein using eine Exception einfach schlucken würde und diese damit nicht mehr nach außen propagiert (und dann natürlich auch nicht behandelt werden kann). Bist du dir da 100%-ig sicher?? Meine Erwartungshaltung wäre eigentlich eher, daß C# daraus zwar ein try-catch-finally macht, aber nachdem Dispose()-Aufruf die augetretene Exception "weiterfliegen" läßt, damit sie im Callstack weiter nach oben propagieren kann.
 
Zuletzt bearbeitet:
@toeffi
try{//code}catch{//leer}finally{//code}
So meinte ich dass... du hast natürlich recht, wenn ich nicht explizit angebe dass catch leer ist.
:p

@antred

du kannst sicher noch einen try catch block innerhalb USING einbauen. So wie toeffi geschrieben hat (oder bei mir hier oben), wird das Object auf disposed gesetzt, sobald die Using verlassen wird oder eine Exception im Code aufgetretten hat.

Also meinerseits bauen ich USING nur dann ein, wenn keine kritische Abschnitte ausgeführt werden.
 
Zuletzt bearbeitet:
Hmm, ich verstehe immer noch nicht, warum genau du meinst, daß man using; bei kritischen Codeabschnitten vermeiden sollte? Was kann Schlimmes passieren, wenn man es trotzdem tut?
 
Weil "using" laut toeffi ein Try-Finally benutzt. Mit "kritischen Abschnitten" meint roker wohl, dass man diese mit einem Try-Catch absichern sollte. Das wäre aber dann mit einem Using doppelt gemoppelt, weil Try-Catch selbst durch ein Finally erweitert werden kann und man im Vergleich zum Using auch noch bestimmen kann wie Objekte genau freigegeben werden.
 
Ich habe mir mal den IL Code von Try..Finally und Using angeschaut und es gibt meiner Meinung nach keinen Unterschied. Ich denke Using ist schlicht nur eine Vereinfachung um sich das Try...Finally im Code sparen zu können, wenn man nur das Dispose im Finally Block aufrufen will. Die Exception wird analog zu Try...Finally nach aussen weiter gereicht. Ob man es nun verwendet, bleibt Geschmacksache...

Ich zum Beispiel würde eher dazu tendieren es nicht einzusetzen, da im Hintergrund vom Compiler etwas hinzugefügt wird, auf das ich keinen Einfluß habe (Aufruf der Dispose Methode). Beim Finally habe ich jedoch die volle Kontrolle und kann dann entsprechend meinen eigenen "Cleanup" Code schreiben und somit direkten Einfluß nehmen, z.B. weitere Methoden vor der Zerstörung aufrufen oder ähnliches. Ebenso muss ich bei Using mit mehreren IDisposable Objekten in meinen Augen unnötige Schachtelungen vornehmen, was den eigentlichen Code immer weiter "nach rechts verschiebt".

Aber wie gesagt es bleibt Geschmacksache, der eine nimmt es, der andere nicht...
 
Zurück
Oben