Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort zur 5. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Klassendesign
4 Vererbung, Polymorphie und Interfaces
5 Delegates und Ereignisse
6 Weitere .NET-Datentypen
7 Weitere Möglichkeiten von C#
8 Auflistungsklassen (Collections)
9 Fehlerbehandlung und Debugging
10 LINQ to Objects
11 Multithreading und die Task Parallel Library (TPL)
12 Arbeiten mit Dateien und Streams
13 Binäre Serialisierung
14 Einige wichtige .NET-Klassen
15 Projektmanagement und Visual Studio 2010
16 XML
17 WPF – Die Grundlagen
18 WPF-Containerelemente
19 WPF-Steuerelemente
20 Konzepte der WPF
21 Datenbindung
22 2D-Grafik
23 ADO.NET – verbindungsorientierte Objekte
24 ADO.NET – Das Command-Objekt
25 ADO.NET – Der SqlDataAdapter
26 ADO.NET – Daten im lokalen Speicher
27 ADO.NET – Aktualisieren der Datenbank
28 Stark typisierte DataSets
29 LINQ to SQL
30 Weitergabe von Anwendungen
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual C# 2010 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2010

Visual C# 2010
geb., mit DVD
1295 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1552-7
Pfeil 7 Weitere Möglichkeiten von C#
Pfeil 7.1 Namensräume (Namespaces)
Pfeil 7.1.1 Zugriff auf Namespaces
Pfeil 7.1.2 Die »using«-Direktive
Pfeil 7.1.3 Globaler Namespace
Pfeil 7.1.4 Vermeiden von Mehrdeutigkeiten
Pfeil 7.1.5 Namespaces festlegen
Pfeil 7.1.6 Der ::-Operator
Pfeil 7.2 Generics – generische Datentypen
Pfeil 7.2.1 Lösung mit einer generischen Klasse
Pfeil 7.2.2 Typparameter mit Constraints einschränken
Pfeil 7.2.3 Generische Methoden
Pfeil 7.2.4 Generics und Vererbung
Pfeil 7.2.5 Konvertierung von Generics
Pfeil 7.2.6 Generische Delegates
Pfeil 7.2.7 Generische Klassen in der .NET-Klassenbibliothek
Pfeil 7.3 Operatorüberladung
Pfeil 7.3.1 Syntax der Operatorüberladung
Pfeil 7.3.2 Operatorüberladungen in »GeometricObjectsSolution«
Pfeil 7.3.3 »true«- und »false«-Operatoren
Pfeil 7.3.4 Benutzerdefinierte Konvertierungen
Pfeil 7.4 Indexer
Pfeil 7.4.1 Überladen von Indexern
Pfeil 7.4.2 Parameterbehaftete Eigenschaften
Pfeil 7.5 Erweiterungsmethoden
Pfeil 7.6 Implizit typisierte Variablen (Typinferenz)
Pfeil 7.7 Lambda-Ausdrücke
Pfeil 7.8 Anonyme Typen
Pfeil 7.9 Nullable-Typen
Pfeil 7.10 Attribute
Pfeil 7.10.1 Das »Flags«-Attribut
Pfeil 7.10.2 Anmerkungen zu den Attributen
Pfeil 7.10.3 Benutzerdefinierte Attribute
Pfeil 7.10.4 Attribute auswerten
Pfeil 7.10.5 Festlegen der Assembly-Eigenschaften
Pfeil 7.11 Partielle Methoden
Pfeil 7.12 Dynamisches Binden
Pfeil 7.12.1 Eine kurze Analyse
Pfeil 7.12.2 Dynamische Objekte
Pfeil 7.13 Unsicherer (unsafe) Programmcode – Zeigertechnik in C#
Pfeil 7.13.1 Einführung
Pfeil 7.13.2 Das Schlüsselwort »unsafe«
Pfeil 7.13.3 Deklaration von Zeigern
Pfeil 7.13.4 Die »fixed«-Anweisung
Pfeil 7.13.5 Zeigerarithmetik
Pfeil 7.13.6 Der Operator »->«

7 Weitere Möglichkeiten von C#

Wir haben nun alle wichtigen Facetten der Objektorientierung beleuchtet. Es gibt jedoch noch viele andere Themen, die in der Programmierung mit .NET eine wichtige Rolle einnehmen und denen wir uns in diesem Kapitel widmen. Dazu gehören beispielsweise Namensräume, Generics, die Überladung von Operatoren, Indexer, Erweiterungsmethoden, Lambda-Ausdrücke, Attribute, das dynamische Binden, die Deklaration von Zeigern u. v. m.


Galileo Computing - Zum Seitenanfang

7.1 Namensräume (Namespaces) Zur nächsten ÜberschriftZur vorigen Überschrift

Die .NET-Klassenbibliothek enthält zahlreiche Klassendefinitionen, die dem Entwickler im Bedarfsfall ihre individuellen Dienste über Methoden bereitstellen. Sie können davon ausgehen, dass sich das Angebot im Laufe der Zeit durch neue Technologien noch deutlich erweitern wird. Dabei sind die benutzerdefinierten Klassen noch nicht berücksichtigt.

Gäbe es für dieses große Angebot keine besondere Verwaltungsstruktur, wäre das Chaos perfekt. Erfahrene Entwickler wissen, wie schwierig es ist, aus den circa 5000 bis 6000 verschiedenen Betriebssystemfunktionen eine bestimmte zu finden. Da hilft auch kein von Microsoft sorgfältig gewählter, beschreibender Funktionsname weiter: Die Suche gleicht dem Stöbern nach der berühmten Stecknadel im Heuhaufen.

Dieser Problematik waren sich die .NET-Architekten bewusst und haben daher das Konzept der Namespaces (Namensräume) eingeführt. Namespaces sind hierarchische, logische Organisationsstrukturen. Sie kategorisieren Typdefinitionen, um das Auffinden einer bestimmten Funktionalität auf ein Minimum an Aufwand zu reduzieren und Mehrdeutigkeiten zu vermeiden.

Namespaces lassen sich sehr gut mit der Ordnerstruktur eines Dateisystems vergleichen. Dabei ähnelt ein Namespace einem Verzeichnis. Jedes Verzeichnis enthält Dateien, die meist logisch miteinander in Beziehung stehen: Beispielsweise können die Dateien eine Anwendung bilden, oder es handelt sich um gemeinsam verwaltete Benutzerdokumente. Innerhalb eines Namespace werden ebenfalls logisch zusammenhängende Typen verwaltet. Beim Vergleich mit dem physikalischen Dateisystem entspricht eine Typdefinition einer Datei. Innerhalb eines Ordners muss der Name einer Datei eindeutig sein – innerhalb eines Namespace gilt dasselbe für die Typbezeichner. Im Dateisystem können Verzeichnisse Unterverzeichnisse enthalten, um eine feinere Gliederung zu erzielen. Aus denselben Gründen können Namespaces weitere Namespaces einbetten.

Ein Namespace ist ein Verwaltungskonstrukt, in dem ein oder mehrere Typen logisch gruppiert werden, die funktional in einer verwandtschaftlichen Beziehung stehen. Beispielsweise sind alle Klassen des .NET-Frameworks, die Dateioperationen zur Verfügung stellen, dem Namespace System.IO zugeordnet. Der größte Namespace ist der mit der Bezeichnung System. Er enthält die wichtigsten .NET-Typen und hat aus organisatorischen Gründen weitere, untergeordnete Namespaces.

Zwischen einem Namespace und einer Bibliotheksdatei (DLL), die Typdefinitionen enthält, besteht keine 1:1-Beziehung. Vielmehr kann sich ein Namespace über mehrere DLL-Dateien erstrecken. Umgekehrt können in einer DLL-Datei auch mehrere Namespaces definiert werden.

Grundsätzlich ist jeder Typ Mitglied eines Namespace. Folgerichtig wird auch jedweder Programmcode in Namespaces verwaltet. Jedes neue Projekt eröffnet dazu einen neuen Namespace, in dem alle Typen des aktuellen Projekts verwaltet werden.


Galileo Computing - Zum Seitenanfang

7.1.1 Zugriff auf Namespaces Zur nächsten ÜberschriftZur vorigen Überschrift

Es ist ein Irrtum zu glauben, man könne ohne weitere Maßnahme auf jeden beliebigen Namespace und eine darin verwaltete Klasse Zugriff erhalten. Vielmehr muss dem Projekt die Datei bekannt gegeben werden, die den erforderlichen Namespace enthält.

Damit jedes Projekt von Anfang an eine gewisse Grundfunktionalität hat, werden die wichtigsten Bibliotheken von Anfang an eingebunden. Sie finden die Liste der Dateiverweise im Projektmappen-Explorer, wenn Sie den Knoten Verweise im Projektmappen-Explorer öffnen. Die Dateiendung DLL wird in der Verweisliste nicht mit angegeben, da es sich nur um DLLs handeln kann (siehe Abbildung 7.1).

Abbildung 7.1 Der geöffnete Knoten »Verweise«

Damit stehen dem Entwickler schon beim Öffnen eines neuen Projekts sehr viele Klassen zur Verfügung – nämlich die, die in den Bibliotheken enthalten sind, auf die verwiesen wird. Sollte es sich im Laufe der Entwicklungszeit herausstellen, dass darüber hinaus noch weitere benötigt werden, muss die Verweisliste um die entsprechenden Bibliotheken ergänzt werden. Dazu öffnen Sie das Kontextmenü des Knotens Verweise im Projektmappen-Explorer und wählen Verweis hinzufügen... Daraufhin wird das Dialogfenster aus Abbildung 7.2 angezeigt. In der Registerkarte .NET wird die gewünschte Datei markiert und über die Schaltfläche OK zur Liste der ausgewählten Komponenten hinzugefügt. In Tabelle 7.1 sind alle Registerkarten des Dialogs erläutert.

Abbildung 7.2 Der Dialog zum Hinzufügen von Verweisen


Tabelle 7.1 Die Registerkarten des Dialogs »Verweis hinzufügen«

Registerkarte Beschreibung

.NET

Hier wählen Sie die Bibliotheken aus, die sich an zentraler Stelle (Global Assembly Cache – GAC) eingetragen haben. Diese Lokalität wird durch den Pfad \Windows\assembly beschrieben.

COM

Möchten Sie eine Komponente nutzen, die für COM/ActiveX entwickelt worden ist, suchen Sie die gewünschte Komponente hier.

Projekte

Hier werden Ihnen die Projekte zur Auswahl angeboten, die sich in derselben Projektmappe mit dem aktuellen Projekt befinden.

Durchsuchen

Ist die Bibliothek nicht im Global Assembly Cache eingetragen, können Sie über diese Lasche zum Speicherort der DLL-Datei navigieren.

Aktuell

Hier finden Sie eine Liste derjenigen Bibliotheken, die Sie während Ihrer letzten Sessions hinzugefügt haben.


Wenn Sie wissen, welche Klasse Sie in Ihrem Projekt benötigen, stellt sich nur noch die Frage, in welcher Datei die Klasse zu finden ist. Die Lösung ist sehr einfach, wenn Sie sich das Datenblatt der entsprechenden Klasse in der .NET-Dokumentation ansehen. Darin werden Sie sowohl die Angabe des Namespace finden, dem die Klasse zugeordnet ist, als auch die Angabe der zugehörigen Bibliotheksdatei.


Galileo Computing - Zum Seitenanfang

7.1.2 Die »using«-Direktive Zur nächsten ÜberschriftZur vorigen Überschrift

Standardmäßig muss beim Zugriff auf eine Klasse auch der Namespace angeführt werden, dem die Klasse zugeordnet ist. Betrachten wir dazu das schon häufig benutzte Beispiel der Methode WriteLine der Klasse Console, die zum Namespace System gehört. Um im Konsolenfenster eine Ausgabe zu erhalten, müssten Sie streng genommen


System.Console.WriteLine("Hallo Welt");

schreiben. Eine Angabe, die aus Namespace und Klassenname besteht, wird als vollqualifizierter Name bezeichnet und ähnelt einer kompletten Pfadangabe im physikalischen Dateisystem. Vollqualifizierte Namen führen oft zu sehr langen, unübersichtlichen und schlecht lesbaren Ausdrücken im Programmcode, insbesondere wenn mehrere Namespaces ineinander verschachtelt sind. C# bietet uns mit der using-Direktive Abhilfe. Mit


using System;

können Sie an späterer Stelle im Programmcode auf alle Typen des so bekannt gegebenen Namespace unter Angabe des Typbezeichners zugreifen, ohne den vollqualifizierten Namen angeben zu müssen:


Console.WriteLine("Hallo Welt");

using-Direktiven stehen außerhalb der Klassendefinitionen und beziehen sich nur auf die Quellcodedateien, in denen sie angegeben sind.


Galileo Computing - Zum Seitenanfang

7.1.3 Globaler Namespace Zur nächsten ÜberschriftZur vorigen Überschrift

In .NET gibt es einen sogenannten globalen Namespace. Diesem werden die folgenden Elemente zugeordnet:

  • alle Toplevel-Namespaces
  • alle Typen, die keinem Namespace zugeordnet sind

Der Zugriff auf den globalen Namespace unterliegt einer speziellen Syntax und wird in Abschnitt 7.1.6, »Der ::-Operator«, erläutert.


Galileo Computing - Zum Seitenanfang

7.1.4 Vermeiden von Mehrdeutigkeiten Zur nächsten ÜberschriftZur vorigen Überschrift

Namespaces dienen zur Strukturierung und Gruppierung von Klassen ähnlicher Merkmale, aber auch zur Vermeidung von Mehrdeutigkeiten. Konflikte aufgrund gleicher Typbezeichner werden durch Namespaces vermieden. Allerdings kann die Bekanntgabe mehrerer Namespaces mit using Probleme bereiten, sollten in zwei verschiedenen Namespaces jeweils gleichnamige Typen existieren. Dann hilft using auch nicht weiter. Angenommen, in den beiden fiktiven Namespaces MyApplication und YourApplication wäre jeweils eine Klasse Person definiert, dann würde das folgende Codefragment wegen der Uneindeutigkeit des Klassenbezeichners einen Fehler verursachen:


using MyApplication;
using YourApplication;
class Demo {
  static void Main(string[] arr) {   
    Person obj = new Person();
    ...
  }   
}

Die Problematik lässt sich vermeiden, wenn der Namespace der Klasse Person näher spezifiziert wird, beispielsweise mit:


MyApplication.Person person = new MyApplication.Person();

Es gibt auch noch eine weitere Möglichkeit, um den Eindeutigkeitskonflikt oder eine überlange Namespace-Angabe zu vermeiden: die Definition eines Alias. Während die einfache Angabe ohne Alias hinter using nur einen Namespace erlaubt, ersetzt ein Alias den vollständig qualifizierenden Typbezeichner. Damit könnten die Klassen Person in den beiden Namespaces auch wie folgt genutzt werden:


using FirstPerson = MyApplication.Person;
using SecondPerson = YourApplication.Person;
...
FirstPerson person = new FirstPerson();

Genauso können Sie, falls Sie Spaß daran haben, die Klasse Console umbenennen, z. B. in Ausgabe:


using Ausgabe = System.Console;
...
Ausgabe.WriteLine("Hallo Welt");


Galileo Computing - Zum Seitenanfang

7.1.5 Namespaces festlegen Zur nächsten ÜberschriftZur vorigen Überschrift

Jedem neuen C#-Projekt wird von der Entwicklungsumgebung automatisch ein Namespace zugeordnet. Standardmäßig sind Namespace- und Projektbezeichner identisch.

Solange sich Typen innerhalb desselben Namespace befinden, können sie sich gegenseitig direkt mit ihrem Namen ansprechen. Die Klassen DemoA, DemoB und DemoC des folgenden Codefragments sind demselben Namespace zugeordnet und benötigen deshalb keine vollqualifizierte Namensangabe.


namespace MyApplication {
  class DemoA {/*...*/}
  class DemoB {/*...*/}
  class DemoC {/*...*/}
}

Jeden Namespace können Sie selbstverständlich nach eigenem Ermessen benennen. Häufig verwenden die Unternehmen dazu Ihren Unternehmensnamen. Zudem lassen sich auch mehrere Namespaces angeben, wie das folgende Codefragment zeigt:


using System;
using MyApp;
using ConsoleApplication;
namespace ConsoleApplication {
  class Program {
    static void Main(string[] args) {
      // erfordert: using MyApp; 
      Demo obj = new Demo();
    }
  }
}
namespace MyApp {
  public class Demo {
    public void Test() {
      // erfordert: using ConsoleApplication; 
      Program obj = new Program();
    }
  }
}

Das Beispiel zeigt die beiden parallelen Namespaces ConsoleApplication und MyApp. Jeder enthält eine Klasse mit einer Methode, in der ein Objekt vom Typ der Klasse aus dem anderen Namespace instanziiert wird. Da der Zugriff Namespace-übergreifend ohne die Angabe des vollqualifizierten Bezeichners erfolgt, müssen beide Namespaces durch using bekannt gegeben werden.

Eingebettete Namespaces

Ein Namespace kann mit einem Ordner des Dateisystems verglichen werden. So wie ein Ordner mehrere Unterordner enthalten kann, können auch Namespaces eine hierarchische Struktur bilden. Der oberste Namespace, der entweder dem Projektnamen entspricht oder manuell verändert worden ist, bildet die Wurzel der Hierarchie, ähnlich einer Laufwerksangabe.

Soll dieser Stamm-Namespace eine feinere Strukturierung aufweisen und eingebettete Namespaces verwalten, wird innerhalb eines Namespace ein weiterer, untergeordneter Namespace definiert:


namespace Outer {
  class DemoA {
    static void Main(string[] args) {
      DemoB obj = new DemoB();
    }
  }
  namespace Inner {
    class DemoB {
      public void TestProc() {/*...*/}
    }
  }
}

Ein Typ in einem übergeordneten Namespace hat nicht automatisch Zugriff auf einen Typ in einem untergeordneten Namespace. Damit das Codefragment auch tatsächlich fehlerfrei kompiliert werden kann, ist es erforderlich, mit


using Outer.Inner;

den inneren Gültigkeitsbereich den Typen in der übergeordneten Ebene bekannt zu geben.


Galileo Computing - Zum Seitenanfang

7.1.6 Der ::-Operator topZur vorigen Überschrift

Auch für Namespaces lässt sich ein Alias festlegen, beispielsweise:


using EA = System.IO;

Sie können nun wie gewohnt den Punktoperator auf den Alias anwenden, also:


EA.StreamReader reader = new EA.StreamReader("...");

Seit dem .NET Framework 2.0 bietet sich aber auch die Möglichkeit, mit dem ::-Operator auf Typen aus Namespace-Aliasen zu verweisen.


EA::StreamReader reader = new EA::StreamReader("...");

Die Einführung des ::-Operators hatte den Grund, unschöne Effekte zu vermeiden, die sich im Zusammenhang mit Namespace-Aliasen und dem Punkt-Operator ergeben können. Sehen Sie dazu den folgenden Beispielcode an:


using System;
using Document = Tollsoft.Developement.Office;
namespace ConsoleApplication {
  class Program {
    static void Main(string[] args) {
      Document.Demo demo = new Document.Demo();
    }
  }
}
namespace Tollsoft.Developement.Office {
  class Demo { }
}

Richten Sie Ihr Augenmerk auf die Anweisung in der Methode Main. Die Syntax Document.Demo lässt nicht eindeutig erkennen, ob es sich bei Document um einen Namespace handelt oder um einen Namespace-Alias. Zudem wäre auch noch denkbar, dass Demo eine innere Klasse von Document ist. Die Verwendung des ::-Operators würde zumindest demjenigen Entwickler eine Hilfe sein, der sich in den Quellcode neu einarbeiten muss. Besser wäre also die folgende Anweisung:


Document::Demo demo = new Document::Demo();

Noch bedeutender wird der ::-Operator, wenn in einer anderen Assembly, auf die im Projekt verwiesen wird, ein Namespace oder ein Typ mit dem gleichen Namen wie der Alias angeboten wird. Die Syntax Document.Demo würde dann sogar zu einem Fehler führen, während Document::Demo eindeutig ist.


Hinweis

Man sollte diese Überlegung nicht einfach vom Tisch wischen, wenn aktuell kein Konflikt mit einem Namespace oder Typ in einer anderen Assembly vorliegt. Möglicherweise wird die Assembly, auf die verwiesen wird, später in einer neueren Version ausgeliefert. Spätestens dann könnte es zu einem Eindeutigkeitskonflikt kommen.


Der ::-Operator gestattet auch den Zugriff auf den globalen Namespace. Dazu müssen Sie nur das C#-Schlüsselwort global vor den Namespace setzen. Auf diese Weise können Sie auf Typen zugreifen, die Sie nicht explizit einem Namespace zugeordnet haben (siehe Abbildung 7.3).

Abbildung 7.3 Der globale Namespace

Halten wir an dieser Stelle Folgendes zum Einsatz des ::-Operators fest:

  • Der ::-Operator ist notwendig, um mithilfe von global auf den globalen Namespace zuzugreifen.
  • Der ::-Operator sollte benutzt werden, um bei der Verwendung eines Namespace-Alias Eindeutigkeitskonflikte zu vermeiden.


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Visual C# 2010

Visual C# 2010
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: C/C++






 C/C++


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2010
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern