Sie sind auf Seite 1von 6

Types and members

Als Objekt-orientierte Sprache unterstützt C# die Konzepte: encapsulation / Verkapselung,


inheritance / Vererbung, und polymorphism / Polymorphie. Eine Klasse kann von EINER
Elternklasse direkt erben und mehere Interfaces implemetieren. Methoden, welche virtual
methods einer Elternklasse überschreiben, brauchen das override Schlüsselwort, als einen
Weg um versehentliche Umdefinierung zu verhindern. In C# ein struct ist eine lightweight
class, es ist ein stack-zugewiesener Typ, welcher interfaces implementieren kann aber keine
Vererbung unterstüzt. C# stellt außerdem records bereit, was class Typen sind, dessen
hauptsächlicher Zweck es ist Daten Werte zu sepichern.

Classes and objects


Klassen sind die fundamentalsten C# Typen. Eine Klasse ist eine Datenstruktur, die states /
Zustände (fields) und actions / Aktionen (methods and other function members) in einer
Einheit kombinieren. Eine Klasse stellt eine Definition für Instanzen der Klasse bereit, auch
bekannt als Objekte. Klassen unterstützen Vererbung und Polymorphie, Mechanismen
womit abgeleitet Klassen Basis-Klassen erweitern und spezialisieren können.
Neue Klassen werden erstellt durch Klassen deklarationen. Eine Klassen deklaration startet
mit einem header. Der header spezifiziert:
- Die attributes und modifiers der Klasse.
- Den Namen der Klasse.
- Die Basis-Klasse (wenn man denn von einer erbt).
- Die interfaces die von der Klasse implementiert werden.
Nach dem header kommt der class body / Klassenkörper , welcher aus eine Liste von
member deklarationen besteht die zwischen den delimiters / Trennzeichen { } stehen.
Der folgende Code zeigt eine Deklaration einer simplen Klasse mit dem Namen „Point“:
public class Point
{
public int X { get; }
public int Y { get; }

public Point(int x, int y) => (X, Y) = (x, y);


}

Instanzen von Klassen werden durch den new Operator erstellt, dieser stellt Speicher bereit
für eine neue Instanz, ruft einen constructor auf um die Instanz zu initialiseren und eine
Referenz zur Instanz zurückgibt. Die folgenden Statements erstellen 2 „Point“ objects und
lagern Referenzen zu diesem Objekten in 2 Variablen.
var p1 = new Point(0, 0);
var p2 = new Point(10, 20);
Der Speicher besetzt von einem Objekt wird automatisch zurückgefordert, wenn das Objekt
nicht mehr erreichbar ist. Es nicht notwendig oder möglich explizit in C# Objecte
freizugeben.
Type parameters
Generische Klassen definieren Typ Parameter. Typ Parameter sind eine Liste von Type
Parametern, umschlossen von Winkel Klammern. Type Parameter stehen hinter dem
Klassennamen. Die Typ Parameter können im body der Klassendeklaration genutzt werden
um die member der Klasse zu definieren. Im folgenden Beispiel sind die Typ Parameter
TFirst und TSecond.
public class Pair<TFirst, TSecond>
{
public TFirst First { get; }
public TSecond Second { get; }

public Pair(TFirst first, TSecond second) =>


(First, Second) = (first, second);
}

Einen Klassentyp der mit Typ Parametern deklariert ist nennent man eine generic class
type / generischer Klassentyp. Struct, interface und delegate types können auch generisch
sein. Wenn die generische Klasse benutzt wird müssen Typ arguments / Argumente für
jeden der Typ Parameter bereitgestellt werden.
var pair = new Pair<int, string>(1, "two");
int i = pair.First; // TFirst int
string s = pair.Second; // TSecond string

Ein generischer Typ mit Typ Argumenten, wie oben, wird contructed type / Konsturierter
Typ gennant.
Base classes
Eine Klassendeklaration kann ein ein base class spezifizieren. Hinter dem Klassennamen und
Type Parametern kann ein Doppelpunkt stehen und dann kommt der Name der Basis-
Klasse. Die base class weg zu lassen ist im Grunde wie von object zu erben. Im folgenden
Beispiel heisst die base class, von „Point3d“, „Point“. Die base class von „Point” ist object.
public class Point3D : Point
{
public int Z { get; set; }

public Point3D(int x, int y, int z) : base(x, y)


{
Z = z;
}
}

Eine Klasse erbt die member ihrer base class. Vererbung bedeutet das eine Klasse implizit
fast alle member ihrer base class erbt. Eine Klasse erbt nicht die instance und static
contructors und den finalizer. Eine derived Klasse kann außerdem neue Member zu den
hinzufügen die sie bereits erbt, aber sie kann nicht die Definition eine verebten members
entfernen. Im vorherigen Beispiel erbt „Point3D“ die „X“ und „Y“ member von Point, jede
Instanz von „Point3D“ wird drei properties / Eigenschaften beinhalten, „X“, „Y“ und „Z“.
Eine implizite conversion / Umwandlung existiert von jedem Klassentyp zu jeder ihres Basis-
Klassentypen. Eine Variable eines Klassentypes kann eine Instanz dieses Klassentypes
referenzieren oder die einer abgeleiteten Klasse. Zum Beispiel kann, frühere
Klassendefinition gegeben, eine Variable des Typen „Point“ eine Referenz zu „Point“ oder
„Point3D“ speichern:
Point a = new Point(10, 20);
Point b = new Point3D(10, 20, 30);

Structs
Klassen definieren Typen, die Vererbung und Polymorphie unterstützen. Sie erlauben einen
geistreiche Verhalten basierend auf der Hierarchie abgeleiteter Klassen. Im Kontrast dazu
sind struct Typen simplere Typen, wessen Primärfunktion es ist Datenwerte zu lagern.
Structs können keinen Basistyp deklarieren, sie erben implizit vom System.ValueType. Man
kann keine struct Typen von anderen struct Typen ableiten. Sie sind implizit versiegelt.
public struct Point
{
public double X { get; }
public double Y { get; }

public Point(double x, double y) => (X, Y) = (x, y);


}

Interfaces
Ein Interface definiert einen Vertrag der von Klassen und Structs implementiert werden
kann. Man definiert ein Interface um Fähigkeiten zu deklarieren die von distinct types geteilt
werden. Ein Beispiel wäre, das System.Collections.Generic.IEnumerable<T> Interface
definiert einen konstanten Weg um sich durch alle Items in einer Sammlung zu bewegen,
wie zB. durch ein Array. Ein Interface kann Methoden, Eigenschaften, Events und indexers
beinhalten. Ein Interface stellt üblicherweise keine Implementationen bereit von den
member die es definiert, es spezifiziert nur die member die bereitgestellt werden müssen
von den Klassen oder structs die das Interface implementieren.
Interfaces können Mehrfachvererbung / multiple inheritance verwenden. Im folgenden
Beispiel erbt das Interface „IComboBox“ sowohl von „ITextBox“, als auch von „IListBox“.
interface IControl
{
void Paint();
}

interface ITextBox : IControl


{
void SetText(string text);
}

interface IListBox : IControl


{
void SetItems(string[] items);
}

interface IComboBox : ITextBox, IListBox { }

Klassen und Structs können mehrere Interfaces implementieren. Im nachfolgenden Beispiel


implementiert die Klasse „EditBox“ sowohl „IControl“ als auch „IDataBound“.
interface IDataBound
{
void Bind(Binder b);
}

public class EditBox : IControl, IDataBound


{
public void Paint() { }
public void Bind(Binder b) { }
}

Wenn eine Klasse oder ein struct ein bestimmtes Interface implementiert, dann können
Instanzen dieser Klasses, oder dieses Structs implizit zu diesem Interface Typ umgewandelt
werden. Zum Beispiel:
EditBox editBox = new EditBox();
IControl control = editBox;
IDataBound dataBound = editBox;

Enums
Ein Enum Typ definiert eine Reihe von Konstanten Werten. Das folgende Enum deklariert
Konstanten, die verschiedene Wurzelgemüse definieren.
public enum SomeRootVegetable
{
HorseRadish,
Radish,
Turnip
}

Man kann außerdem ein Enum definieren, dass es in Kombination mit flags funktioniert. Die
nachfolgende Deklaration deklariert eine Reihe von flags für die 4 Jahreszeiten. Jede
Kombination der Jahreszeiten benutzt werden, sogar ein ALL Wert der alle Jahreszeiten
beinhaltet.
[Flags]

public enum Seasons


{
None = 0,
Summer = 1,
Autumn = 2,
Winter = 4,
Spring = 8,
All = Summer | Autumn | Winter | Spring
}

Da nächste Beispiel zeigt Deklarationen der beiden vorherigen enums:


var turnip = SomeRootVegetable.Turnip;

var spring = Seasons.Spring;


var startingOnEquinox = Seasons.Spring | Seasons.Autumn;
var theYear = Seasons.All;

Nullable Types:
Variablen eines jenen Typen kann man als non-nullable oder nullable deklarieren. Eine
nullbare Variable kann einen zusätzlichen null Wert halten, ein indiz für keinenh Wert.
Nullbare Werte-Typen (structs oder enums) werden repräsentiert durch
System.Nullable<T>. Nicht nullbare und nullbare Referenz-Typen werden beide
repräsentiert durch den unterliegenden Referenz-Typen. Der Unterschied ist repräsentiert
durch Metadaten die vom compiler und einigen librarys gelesen werden. Der compiler
warnt einen wenn man nullbare Referenzen, entreferenziert weden ohne vorher ihren Wert
gegen null zu überprüfen. Der compiler warnt einen außerdem wenn nicht nullbare
Referenzen ein Wert zugeteilt wird, der möglicherweise null ist. Das nächste Beispiel
deklariert ein nullbaren int, der mit null initialisiert wird. Dann setzt es den Wert zu 5. Es
demonstirert das gleiche Konzept mit einem nullbaren string.
int? optionalInt = default;
optionalInt = 5;
string? optionalText = default;
optionalText = "Hello World.";

Tuples
C# unterstützt Tupel, welche eine präzise Syntax bereitstellen um mehrere Datenelemente
einzugruppieren in einer leichten Datenstruktur. Man instanziiert ein Tupel in dem man die
Typen und Namen der member zwischen ( und ) schreibt, wie im Beispiel zu sehen ist:
(double Sum, int Count) t2 = (4.5, 3);
Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}.");
// Output:
// Sum of 3 elements is 4.5.

Tupel bieten eine alternative Datenstruktur mit mehreren member, ohne die buildings
blocks zu nutzen die im nächsten Artikel beschrieben werden.

Das könnte Ihnen auch gefallen