E-Book, Deutsch, 272 Seiten
Reihe: O'Reilly`s kurz & gut
E-Book, Deutsch, 272 Seiten
Reihe: O'Reilly`s kurz & gut
ISBN: 978-3-96010-684-5
Verlag: O'Reilly
Format: EPUB
Kopierschutz: 6 - ePub Watermark
Joseph Albahari entwirft Enterprise-Anwendungen auf .NET und auf anderen Plattformen und hat in der Telekommunikation sowie im Gesundheits- und im Bildungswesen gearbeitet. Neben einer Reihe von O'Reilly-Büchern hat er auch LINQPad, das beliebten Query-Tool für LINQ, geschrieben. Ben Albahari ist Mitbegründer von Auditionist, einer Casting-Website für Schauspieler in Großbritannien. Er war fünf Jahre lang Programm-Manager bei Microsoft, wo er an mehreren Projekten arbeitete, darunter am .NET Compact Framework und an ADO.NET. Er ist Mitbegründer von Genamics, einem Tools-Anbieter für C#- und J++-Programmierer, der Software für DNA- und Proteinsequenz-Analysen entwickelt. Bei einer Reihe von O'Reilly-Büchern zu C# war er Co-Autor.
Weitere Infos & Material
Klassen
Die Klasse ist die am häufigsten verwendete Form eines Referenztyps. Die einfachste mögliche Klassendeklaration sieht so aus: class Foo { } Eine komplexere Klassendeklaration kann folgende Elemente enthalten: Vor dem Schlüsselwort class Attribute und Klassenmodifikatoren. Die nicht geschachtelten Klassenmodifikatoren sind public, internal, abstract, sealed, static, unsafe und partial. Hinter Foo Generische Typparameter und Constraints, eine Basisklasse und Schnittstellen. Innerhalb der geschweiften Klammern Klassen-Member (das sind Methoden, Eigenschaften, Indexer, Events, Felder, Konstruktoren, überladene Operatoren, eingebettete Typen und ein Finalizer). Felder Ein Feld ist eine Variable, die ein Member einer Klasse oder eines Struct ist: class Octopus { string name; public int age = 10; } Ein Feld kann den Modifikator readonly haben, um zu verhindern, dass es nach dem Erstellen verändert wird. Einem nur lesbaren Feld kann lediglich während seiner Deklaration oder im Konstruktor des Typs, der es enthält, ein Wert zugewiesen werden. Die Initialisierung eines Felds ist optional. Ein nicht initialisiertes Feld hat einen Standardwert (0, '\0', null, false). Feldinitialisierer werden vor den Konstruktoren in der Reihenfolge ausgeführt, in der sie erscheinen. Aus Gründen der Bequemlichkeit können Sie mehrere Felder desselben Typs in einer kommaseparierten Liste deklarieren. Das ist praktisch für Felder, die die gleichen Attribute und Feldmodifikatoren haben: static readonly int legs = 8, eyes = 2; Konstanten Eine Konstante ist ein Feld, dessen Wert sich nicht ändern kann. Eine Konstante wird statisch beim Kompilieren ausgewertet, und ihr Wert wird bei jeder Verwendung vom Compiler direkt eingesetzt (so ähnlich wie ein Makro in C++). Eine Konstante kann einen der eingebauten numerischen Typen, bool, char und string oder einen enum-Typ nutzen. Eine Konstante wird mit dem Schlüsselwort const deklariert und muss mit einem Wert initialisiert werden: public class Test { public const string Message = "Hello World"; } Eine Konstante ist deutlich restriktiver als ein static readonly-Feld, und zwar sowohl bezüglich der nutzbaren Typen als auch bei der Semantik der Feldinitialisierung. Eine Konstante unterscheidet sich von einem static readonly-Feld zudem darin, dass die Auswertung der Konstanten schon beim Kompilieren stattfindet. Konstanten können auch lokal in einer Methode deklariert werden: static void Main() { const double twoPI = 2 * System.Math.PI; ... } Methoden Eine Methode führt eine Aktivität als Abfolge von Anweisungen aus. Sie kann Eingabedaten vom aufrufenden Code bekommen, indem Parameter spezifiziert werden, und Ausgabedaten an den Aufrufenden zurückgeben, indem ein Rückgabetyp angegeben wird. Eine Methode kann als Rückgabetyp void spezifizieren und damit zeigen, dass sie keinen Wert zurückgeben wird. Sie kann zudem über ref- und out-Parameter Daten an den Aufrufenden übermitteln. Die Signatur einer Methode muss innerhalb des Typs eindeutig sein. Sie besteht aus dem Namen der Methode und der Reihenfolge der Parametertypen (aber nicht den Parameternamen oder dem Rückgabetyp). Expression-bodied Methoden Eine Methode, die aus einem einzelnen Ausdruck besteht, zum Beispiel: int Foo (int x) { return x * 2; } kann kompakter als Expression-bodied Methode geschrieben werden. Ein »dicker Pfeil« ersetzt die geschweiften Klammern und das Schlüsselwort return: int Foo (int x) => x * 2; Expression-bodied Methoden können auch einen void-Rückgabetyp besitzen: void Foo (int x) => Console.WriteLine (x); Lokale Methoden Sie können eine Methode innerhalb einer anderen Methode definieren: void WriteCubes() { Console.WriteLine (Cube (3)); int Cube (int value) => value * value * value; } Die lokale Methode (in diesem Fall Cube) ist nur für die umschließende Methode (WriteCubes) sichtbar. Das vereinfacht den enthaltenden Typ und macht jedem, der sich den Code anschaut, direkt deutlich, dass Cube nirgendwo anders verwendet wird. Lokale Methoden können auf die lokalen Variablen und Parameter der umschließenden Methode zugreifen. Das hat eine Reihe von Konsequenzen, die wir im Abschnitt »Äußere Variablen übernehmen« auf Seite 144 beschreiben. Lokale Methoden können innerhalb anderer Funktionsarten eingesetzt werden, wie Eigenschafts-Accessoren, Konstruktoren usw., sogar innerhalb anderer lokaler Methoden. Lokale Methoden können Iteratoren oder asynchron sein. Methoden, die in Anweisungen auf oberster Ebene deklariert wurden, sind implizit lokal – wir können das wie folgt demonstrieren: int x = 3; Foo(); void Foo() => Console.WriteLine (x); // Wir können auf x // zugreifen Statische lokale Methoden Durch Hinzufügen des Modifikators static zu einer lokalen Methode wird (seit C# 8) verhindert, dass sie die lokalen Variablen und Parameter der umschließenden Methode sieht. Das hilft dabei, eine Kopplung geringer zu gestalten, und verhindert, dass sich die lokale Methode unabsichtlich auf Variablen in der umschließenden Methode bezieht. Methoden überladen Lokale Methoden können nicht überladen werden. Daher können auch Methoden, die in Anweisungen auf oberster Ebene deklariert wurden (die als lokale Methoden behandelt werden), nicht überladen werden. Ein Typ kann Methoden überladen (also mehrere Methoden mit demselben Namen haben), solange sich die Parametertypen unterscheiden. So können zum Beispiel die folgenden Methoden alle gemeinsam im selben Typ existieren: void Foo (int x); void Foo (double x); void Foo (int x, float y); void Foo (float x, int y); Instanzkonstruktoren Konstruktoren führen Initialisierungscode für eine Klasse oder ein Struct aus. Ein Konstruktor wird wie eine Methode definiert, nur dass der Methodenname und der Rückgabewert auf den Namen des Typs reduziert werden, in dem sich der Konstruktor befindet: Panda p = new Panda ("Petey"); // Konstruktor aufrufen public class Panda { string name; // Feld definieren public Panda (string n) // Konstruktor definieren { name = n; // Initialisierungscode } } ... Sie können aus einer Anweisung bestehende Konstruktoren als Expression-bodied Methode schreiben: public Panda (string n) => name = n; Klassen und Structs können Konstruktoren überladen. Eine Überladung ruft über das Schlüsselwort this eine andere auf: public class Wine { public Wine (decimal price) {...} public Wine (decimal price, int year) : this (price) {...} } Wenn ein Konstruktor...