Geschrieben von: Christoph Wille
Kategorie: C#
This printed page brought to you by AlphaSierraPapa
Wer mit C# arbeitet, dem ist das using Schlüsselwort spätestens seit dem obligatorischen Hello World Programm bekannt - als Statement zum Import von Namespaces. Daß using noch einiges mehr zu bieten hat, zeigt dieser Artikel, indem er die using Directive und das using Statement näher beleuchtet.
Beginnen wir bei der bekanntesten Verwendungsart der using Directive:
using System;
Damit wird der System Namespace importiert, was bedeutet, daß man statt der absoluten Referenz System.Console nun auch Console direkt verwenden kann. Kritisch würde es bei einer Applikation die in zwei Namespaces identische Klassennamen verwendet:
using System; namespace Directive { class MainApp { static void Main(string[] args) { // no using statements AspHeute.NamespaceOne.DemoClass oOne= new AspHeute.NamespaceOne.DemoClass(); oOne.SayHello(); AspHeute.NamespaceTwo.DemoClass oTwo= new AspHeute.NamespaceTwo.DemoClass(); oTwo.SayHello(); } } } namespace AspHeute.NamespaceOne { class DemoClass { public void SayHello() { Console.WriteLine("Hello, world! (A.O.D)"); } } } namespace AspHeute.NamespaceTwo { class DemoClass { public void SayHello() { Console.WriteLine("Hello, world! (A.T.D)"); } } }
Dieses Beispiel ist zwar an den Haaren herbeigezogen, aber bei Verwendung von Libraries von Drittherstellern kann es sehr wohl vorkommen, daß Klassen mit identischen Namen auftauchen. Die einfache Variante - das Verwenden von using - wird vom Compiler mit einem Fehler quittiert.
using System; using AspHeute.NamespaceOne; using AspHeute.NamespaceTwo; namespace Directive { class MainApp { static void Main(string[] args) { // error CS0104: 'DemoClass' is an ambiguous reference DemoClass oDemo = new DemoClass(); } } } ...
Hier weiß der Compiler nicht mehr, aus welchem Namespace er die Klasse nehmen soll. Hier kann uns die using Directive allerdings mit ihrer Alias-Funktionalität aushelfen:
using System; using DcOne = AspHeute.NamespaceOne.DemoClass; using DcTwo = AspHeute.NamespaceTwo.DemoClass; namespace Directive { class MainApp { static void Main(string[] args) { DcOne oOne= new DcOne(); oOne.SayHello(); DcTwo oTwo= new DcTwo(); oTwo.SayHello(); } } }
Die beiden identen Klassennamen werden mit Hilfe von using auf eindeutige Namen "umgebogen". Damit erspart man sich dann die volle Angabe der Namespaces wie im ersten Codesample. Natürlich kann man mit der Alias-Funktionalität auch die Namespaces selbst "verbiegen":
using System; using NsOne = AspHeute.NamespaceOne; using NsTwo = AspHeute.NamespaceTwo; namespace Directive { class MainApp { static void Main(string[] args) { NsOne.DemoClass oOne= new NsOne.DemoClass(); oOne.SayHello(); NsTwo.DemoClass oTwo= new NsTwo.DemoClass(); oTwo.SayHello(); } } }
Damit verkürzt man sehr elegant lange Namespaces.
Neben der using Directive gibt es auch das using Statement, das zu Unrecht weniger bekannt ist, denn es ist sehr nützlich in der Welt von .NET: es unterstützt bei der sauberen Auflösung von Resourcen-teuren Objekten.
Wie funktioniert das? Nun, das using Statement ist für Klassen gedacht, die das IDisposable Interface unterstützen (wer die SDK Hilfe installiert hat, kann diesen Hilfe Link klicken, um alle Klassen zu sehen, die dieses Interface implementiert haben). Dieses Interface besitzt genau eine Methode, nämlich Dispose. Diese Methode wird verwendet, um dem Objekt mitzuteilen, daß es seine teuren Resourcen freigeben kann, weil wir das Objekt nicht mehr verwenden werden (und der Garbage Collector es erst später auflöst).
Grundsätzlich sieht das using Statement so aus:
using (expression | type identifier = initializer) { // Code der das Objekt verwendet }
Ein weiterer wichtiger Vorteil des using Statements ist, daß auch im Falle einer Exception die Dispose Methode aufgerufen wird. Man erspart sich also Dispose Aufrufe im finally Teil des Exception Handlings - man kann sie vor allem nicht mehr vergessen, weil sie automatisch aufgerufen werden (für Objekte die mit using erzeugt wurden, klarerweise).
Für eine Applikation die Webseiten grabbt könnte man using wie folgt einsetzen:
using System; using System.Net; namespace Statement { class MainApp { static void Main(string[] args) { WebRequest wrq = WebRequest.Create("http://www.aspheute.com/"); using (WebResponse response = wrq.GetResponse()) { // exception or not, response will always be disposed } } } }
Es fehlt hier der Exception-Handling Code, aber: Dispose wird immer aufgerufen, was speziell bei offenen TCP/IP Verbindungen sehr nützlich ist, denn unlimitiert kann man diese nicht aufmachen. Somit hilft using die Resourcen zu schonen, vor allem mit dem Vorteil, daß man als Programmierer nicht mehr auf den Aufruf von Dispose vergessen kann!
Die using Directive und das using Statement sind beides nützliche Helfer, die die tägliche Arbeit erleichtern - und den Code verbessern können.
This printed page brought to you by AlphaSierraPapa
Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20020318.zip
Das ASP.NET DataGrid selbst erweitern
http:/www.aspheute.com/artikel/20030909.htm
Exception Handling in C#
http:/www.aspheute.com/artikel/20000724.htm
Index Server Abfragen per Web Service
http:/www.aspheute.com/artikel/20021107.htm
On-the-fly Erstellung von vCard's
http:/www.aspheute.com/artikel/20020906.htm
Sichere Konvertierungen von Referenztypen
http:/www.aspheute.com/artikel/20001019.htm
©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.