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

Inhaltsverzeichnis
Vorwort zur 6. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Das Klassendesign
4 Vererbung, Polymorphie und Interfaces
5 Delegates und Ereignisse
6 Strukturen und Enumerationen
7 Fehlerbehandlung und Debugging
8 Auflistungsklassen (Collections)
9 Generics – Generische Datentypen
10 Weitere C#-Sprachfeatures
11 LINQ
12 Arbeiten mit Dateien und Streams
13 Binäre Serialisierung
14 XML
15 Multithreading und die Task Parallel Library (TPL)
16 Einige wichtige .NET-Klassen
17 Projektmanagement und Visual Studio 2012
18 Einführung in die WPF und XAML
19 WPF-Layout-Container
20 Fenster in der WPF
21 WPF-Steuerelemente
22 Elementbindungen
23 Konzepte von WPF
24 Datenbindung
25 Weitere Möglichkeiten der Datenbindung
26 Dependency Properties
27 Ereignisse in der WPF
28 WPF-Commands
29 Benutzerdefinierte Controls
30 2D-Grafik
31 ADO.NET – Verbindungsorientierte Objekte
32 ADO.NET – Das Command-Objekt
33 ADO.NET – Der SqlDataAdapter
34 ADO.NET – Daten im lokalen Speicher
35 ADO.NET – Aktualisieren der Datenbank
36 Stark typisierte DataSets
37 Einführung in das ADO.NET Entity Framework
38 Datenabfragen des Entity Data Models (EDM)
39 Entitätsaktualisierung und Zustandsverwaltung
40 Konflikte behandeln
41 Plain Old CLR Objects (POCOs)
Stichwort

Download:
- Beispiele, ca. 62,4 MB

Buch bestellen
Ihre Meinung?

Spacer
Visual C# 2012 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2012

Visual C# 2012
Rheinwerk Computing
1402 S., 6., aktualisierte und erweiterte Auflage 2013, geb., mit DVD
49,90 Euro, ISBN 978-3-8362-1997-6
Pfeil 16 Einige wichtige .NET-Klassen
Pfeil 16.1 Die Klasse »Object«
Pfeil 16.1.1 Referenzvergleiche mit »Equals« und »ReferenceEquals«
Pfeil 16.1.2 »ToString« und »GetType«
Pfeil 16.1.3 Die Methode »MemberwiseClone« und das Problem des Klonens
Pfeil 16.2 Die Klasse »String«
Pfeil 16.2.1 Das Erzeugen eines Strings
Pfeil 16.2.2 Die Eigenschaften von »String«
Pfeil 16.2.3 Die Methoden der Klasse »String«
Pfeil 16.2.4 Zusammenfassung der Klasse »String«
Pfeil 16.3 Die Klasse »StringBuilder«
Pfeil 16.3.1 Allgemeines
Pfeil 16.3.2 Die Kapazität eines »StringBuilder«-Objekts
Pfeil 16.3.3 Die Konstruktoren der Klasse »StringBuilder«
Pfeil 16.3.4 Die Eigenschaften der Klasse »StringBuilder«
Pfeil 16.3.5 Die Methoden der Klasse »StringBuilder«
Pfeil 16.3.6 Allgemeine Anmerkungen
Pfeil 16.4 Der Typ »DateTime«
Pfeil 16.4.1 Die Zeitspanne »Tick«
Pfeil 16.4.2 Die Konstruktoren von »DateTime«
Pfeil 16.4.3 Die Eigenschaften von »DateTime«
Pfeil 16.4.4 Die Methoden der Klasse »DateTime«
Pfeil 16.5 Die Klasse »TimeSpan«
Pfeil 16.6 Ausgabeformatierung
Pfeil 16.6.1 Formatierung mit der Methode »String.Format«
Pfeil 16.6.2 Formatierung mit der Methode »ToString«
Pfeil 16.6.3 Benutzerdefinierte Formatierung

16 Einige wichtige .NET-KlassenZur nächsten Überschrift


Galileo Computing - Zum Seitenanfang

16.1 Die Klasse »Object«Zur nächsten ÜberschriftZur vorigen Überschrift

Alle Klassen in der Klassenbibliothek des .NET Frameworks sind Mitglieder einer Klassenhierarchie, die sich über viele Verzweigungen in aufgabenspezifische Bereiche gliedert. Alle Klassen, so tief sie auch im Dickicht dieser Hierarchie stecken mögen, lassen sich aber auf die gemeinsame Basisklasse Object zurückführen. Wenn Sie eine benutzerdefinierte Klasse entwickeln, müssen Sie nicht explizit angeben, dass Ihre Klasse von Object abgeleitet ist – diese Ableitung geschieht implizit. Dass sich alle Klassen von Object ableiten, hat eine ganz wesentliche Konsequenz: Jeder Typ des Systems weist ein Minimum gemeinsamer Verhaltensweisen auf.

Object hat nur einen parameterlosen Konstruktor und insgesamt sieben Methoden. Fünf dieser Methoden sind public und damit öffentlich, die beiden anderen Methoden sind protected und erlauben daher nur den Zugriff aus einer erbenden Klasse heraus. Sehen wir uns zunächst in Tabelle 16.1 alle Methoden in einem Überblick an.

Tabelle 16.1 Die Methoden der Klasse »Object«

Methoden Beschreibung

Equals

Diese Methode vergleicht zwei Objektreferenzen und liefert einen booleschen Wert zurück, dem entnommen werden kann, ob die beiden Referenzen auf dasselbe Objekt zeigen.

Finalize

Dient dazu, Ressourcen der Klasse freizugeben, wenn das Objekt zerstört wird.

GetHashCode

Liefert einen eindeutigen numerischen Identifizierer.

GetType

Liefert die Referenz auf eine Type-Instanz zurück, die den Typ des aktuellen Objekts beschreibt.

MemberwiseClone

Dupliziert die aktuelle Instanz und liefert die Referenz auf das Duplikat zurück.

ReferenceEquals

Vergleicht zwei Objektreferenzen und liefert einen booleschen Wert zurück, dem entnommen werden kann, ob die beiden Referenzen auf dasselbe Objekt zeigen.

ToString

Liefert den vollqualifizierten Namen einer Klasse.


Galileo Computing - Zum Seitenanfang

16.1.1 Referenzvergleiche mit »Equals« und »ReferenceEquals«Zur nächsten ÜberschriftZur vorigen Überschrift

Die beiden Methoden Equals und ReferenceEquals sind sich per Definition sehr ähnlich. Es werden zwei Objektvariablen miteinander verglichen, um festzustellen, ob beide dasselbe Objekt im Speicher referenzieren:

Demo object1 = new Demo();
Demo object2;
object2 = object1;
Console.WriteLine(Object.Equals(object1, object2));

Listing 16.1 Referenzvergleich mit »Equals«

In diesem Codefragment wird die Referenz object1 der Variablen object2 zugewiesen. Beide Referenzen zeigen auf dasselbe konkrete Objekt, was der Aufruf der Equals-Methode bestätigt: Es wird true ausgegeben, was als referenzielle Identität der beiden Objektvariablen zu interpretieren ist. In diesem Fall können Sie sogar Equals gegen ReferenceEquals austauschen, am Ergebnis wird sich nichts ändern.

Equals wird sowohl als Instanz- als auch als Klassenmethode angeboten. Die Instanzmethode ist virtual gekennzeichnet und kann von jeder Klasse polymorph überschrieben werden. Die statische Equals-Variante ist nicht überschreibbar, ebenso die ähnlich lautende Methode ReferenceEquals. Damit ist auch garantiert, dass das Ergebnis des Aufrufs einer dieser beiden Methoden immer den Vergleich zwischen zwei Objektreferenzen liefert: Es ist true, wenn beide Referenzen auf ein und dasselbe Objekt verweisen, andernfalls lautet das Ergebnis false.


Galileo Computing - Zum Seitenanfang

16.1.2 »ToString« und »GetType«Zur nächsten ÜberschriftZur vorigen Überschrift

ToString liefert per Definition eine Zeichenfolge zurück, die den vollqualifizierten Namen der Klasse, also einschließlich der Angabe des Namespaces, enthält. Viele Klassen überschreiben diese Methode und haben somit einen abweichenden Rückgabewert. Sehen wir uns das an zwei Beispielen an:

string text = "Visual C# 5.0 ist spitze!";
Console.WriteLine(text.ToString());
int value = 4711;
Console.WriteLine(value.ToString());

Listing 16.2 Rückgabewerte der Methode »ToString«

Die Ausgabe lautet:

Visual C# 5.0 ist spitze!

und

4711

Die Typen String und int überschreiben demnach ToString und liefern den Inhalt der Variablen, auf der die Methode aufgerufen worden ist.

Mit GetType können Sie sich den Typ der Klasse besorgen, allerdings müssen Sie dazu die Rückgabe in einen String konvertieren, z. B.:

int value = 10;
Console.WriteLine(Convert.ToString(value.GetType()));

Jetzt wird nicht der Inhalt der Variablen value, sondern der Datentyp ausgegeben. Sie müssen an dieser Stelle eine Konvertierung vornehmen, weil der Rückgabewert vom Typ Type ist. Die Klasse Type liefert eine Referenz auf das Type-Objekt eines konkreten Objekts zurück. Dieses versetzt uns in die Lage, den Datentyp einer genaueren Analyse zu unterziehen.


Galileo Computing - Zum Seitenanfang

16.1.3 Die Methode »MemberwiseClone« und das Problem des KlonensZur nächsten ÜberschriftZur vorigen Überschrift

Kommen wir zu einem leider etwas nebulösen Teil des .NET Frameworks. Es handelt sich dabei um das Klonen von Objekten. Nebulös deshalb, weil es Microsoft versäumt hat, exakt zu spezifizieren, ob bei den jeweiligen Klonvorgängen eine flache oder tiefe Kopie erzeugt werden soll.

Flache Kopien

Unter einer flachen Kopie versteht man, dass nur eine einfache Kopie eines Objekts erstellt wird. Enthält das zu kopierende Objekt einen Verweis auf ein anderes Objekt (nennen wir es »untergeordnetes Objekt«), wird letzteres nicht dupliziert. Stattdessen verweist auch die Kopie auf dasselbe untergeordnete Objekt wie das Original. Sehen Sie dazu das folgende Listing an, in dem die beiden Klassen Owner und Account beschrieben werden.

public class Owner {
public string Name { get; set; }
public int Alter { get; set; }
}

public class Account {
public int AccountNo { get; set; }
public Owner Owner { get; set; }
}

Listing 16.3 Die Definition der Klassen »Owner« und »Account«

Beachten Sie, dass die Klasse Account eine Eigenschaft vom Typ Owner beschreibt, einem Referenztyp. Das von dieser Eigenschaft referenzierte Objekt ist das oben erwähnte »untergeordnete Objekt«. Wenn wir die flache Kopie eines bestehenden Account-Objekts erzeugen, wird zwar ein neues Account-Objekt erstellt, aber die Kopie verweist in ihrer Eigenschaft Owner auf dasselbe Owner-Objekt wie das Original-Account-Objekt. Das Owner-Objekt wird bei einer flachen Kopie nicht neu erzeugt, also dupliziert.

Die Methode MemberwiseClone der Klasse Object erstellt eine flache Kopie des aktuellen Objekts und liefert die Referenz auf die Kopie. Da MemberwiseClone protected definiert ist, wird eine andere Methode erforderlich, um das Klon an den Aufrufer zurückzugeben. Lassen Sie uns eine solche Methode bereitstellen. Wir können dazu auf das Interface ICloneable des .NET Frameworks zurückgreifen, über das die Methode Clone vorgeschrieben wird.

public class Account : ICloneable {
public int AccountNo { get; set; }
public Owner Owner { get; set; }

// Methode des Interfaces ICloneable

public object Clone() {
return this.MemberwiseClone();
}
}

Listing 16.4 Die Klasse »Account« mit dem Interface »ICloneable«

Clone ruft MemberwiseClone des aktuellen Objekts auf. Dabei werden alle Felder des Originals bitweise kopiert. Das betrifft sowohl die Felder, die auf Wertetypen basieren, als auch die Felder, die auf Referenztypen basieren. Das hat zur Konsequenz, dass die Eigenschaften, die Referenztypen beschreiben, nur die ursprüngliche Referenz in den Klon schreiben, aber kein neues Objekt erzeugen (siehe Abbildung 16.1).

Abbildung

Abbildung 16.1 Prinzip der »flachen Kopie«

Tiefe Kopien

Bei einer tiefen Kopie werden nicht nur die auf Wertetypen basierenden Felder kopiert, sondern auch die Felder, die auf Referenztypen basieren und damit untergeordnete Objekte beschreiben. Bezogen auf die Klassen in Listing 16.4 würde das bedeuten, dass beim Klonen eines Account-Objekts auch eine Kopie des untergeordneten Objekts Owner erstellt wird (siehe Abbildung 16.2).

Die unpräzise Spezifizierung des Klonens bei der Implementierung der Schnittstelle ICloneable hat zu vielen Diskussionen geführt. Soll mit diesem Interface flach oder tief kopiert werden? Es gibt darüber keine allgemeingültige Aussage. Es gibt leider auch keine andere Schnittstelle, die eine tiefe Kopie vorschreiben würde. Da sehr viele Klassen des .NET Frameworks die Schnittstelle ICloneable implementieren, bleibt Ihnen im Zweifelsfall nichts anderes übrig, als die entsprechende Dokumentation zu lesen.

Abbildung

Abbildung 16.2 Prinzip der »tiefen Kopie«

Wenden wir uns wieder den beiden Klasse Owner und Account zu. Optimalerweise implementieren wir in beiden Klassen das Interface ICloneable. Die Methode Clone in der Klasse Owner erzeugt intern mit MemberwiseClone nur einen »einfachen« Klon von sich selbst. In Account hingegen muss darüber hinaus auch noch ein Klon des Eigenschaftswertes Owner erstellt werden. Erst damit ist eine tiefe Kopie eines Account-Objekts gewährleistet.

Im folgenden Beispielprogramm ist der gesamt Code der beiden angesprochenen Klassen gezeigt. Zum Testen des Erfolgs des tiefen Klonens reicht es in diesem Fall völlig aus, in Main den Hashcode des untergeordneten Owner-Objekts abzufragen.

// Beispiel: ..\Kapitel 16\MemberwiseClonen

class Program {
static void Main(string[] args) {
Owner owner = new Owner { Name = "Herbert Meier", Alter = 28 };
Account account = new Account { Owner = owner, AccountNo = 1 };

// Erstellen einer tiefen Kopie

Account copy = (Account)account.Clone();
Console.WriteLine("Hash des Originals: {0}",
account.Owner.GetHashCode());
Console.WriteLine("Hash der Kopie: {0}", copy.Owner.GetHashCode());
Console.ReadLine();
}
}

public class Owner : ICloneable {
public string Name { get; set; }
public int Alter { get; set; }

public object Clone()
{
return this.MemberwiseClone();
}
}

public class Account : ICloneable {
public int AccountNo { get; set; }
public Owner Owner { get; set; }

public object Clone()
{
Account acc = (Account)MemberwiseClone();
acc.Owner = (Owner)Owner.Clone();
return acc;
}
}

Listing 16.5 Erstellen einer »tiefen Kopie«

Der Prozess des tiefen Kopierens muss den gesamten Objektgraphen erfassen und alle darin beschriebenen Objekte duplizieren. Am Ende haben die geklonten Objekte keinerlei Bezug mehr zu ihrem Original. Eine tiefe Kopie zu erstellen ist daher nicht immer so einfach, wie dieses Beispielprogramm vielleicht suggerieren mag. Je nach Typ und je nachdem, ob untergeordnete Objekte ihrerseits selbst wieder untergeordnete Objekte haben, die tief kopiert werden müssen, kann das Erstellen einer tiefen Kopie sehr aufwendig werden.

Es gibt mit dem Prozess der Serialisierung noch eine andere Möglichkeit, eine tiefe Kopie zu erstellen. Das setzt voraus, dass die Klassen mit dem Serializable-Attribut verknüpft sind. Das zu serialisierende Objekt wird einfach in einen Stream vom Typ MemoryStream serialisiert und anschließend sofort wieder deserialisiert.

public object Clone()
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Position = 0;
return formatter.Deserialize(stream);
}

Dabei darf nicht vergessen werden, die aktuelle Position des Streams nach der Serialisierung auf »0« zurückzusetzen.



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# 2012

Visual C# 2012
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 2013
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.


[Rheinwerk Computing]

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