Sprachelemente von C-Sharp
C# ist eine objektorientierte Programmiersprache, die vom Softwarehersteller Microsoft im Rahmen seiner .NET-Initiative eingeführt wurde. Die Syntax von C# ist an die objektorientierte und plattformunabhängige Programmiersprache Java angelehnt. Bei der Entwicklung von C# war Anders Hejlsberg maßgeblich beteiligt, der schon für den Softwarehersteller Borland die Programmiersprache Delphi entwickelte, die auf Pascal basiert.
C# ist ein Akronym für den in der Musik durch ein Kreuz um einen Halbton erhöhten Ton c, das cis - im Englisch "C sharp" ("scharfes C"). Teilweise wird C# auch mit "see sharp" übersetzt oder im deutschen Sprachgebrauch von wenigen Entwicklern "cis" genannt.
Konzept
Neben Konzepten der Programmiersprache Java greift C# auch Konzepte aus C++ sowie der Microsoft-eigenen propietären Sprache VisualBasic auf. Beide Programmiersprachen sind ebenfalls, neben weiteren, als eigenständige Portierungen im .NET Framework verfügbar und nutzbar.
Als eine (favorisierte) Sprache der .NET Plattform wird C# mittels einer virtuellen Laufzeitumgebung (runtime environment) in Form einer virtuellen Maschine (VM) ausgeführt. Durch die Verwendung einer virtuellen Maschine ist es möglich, ein Programm unabhängig von der Plattform (Betriebssystem, Prozessorarchitektur) auszuführen. Ein Programm, das beispielsweise unter dem Betriebssystem Windows auf einer Intel-Architektur entwickelt wurde, kann somit auch auf einem MacOS X-System auf einer PowerPC (PPC)-Architektur ausgeführt werden. Diese Plattformunabhängigkeit ist bei C# bisher aber kaum gegeben, da der Hersteller Microsoft die .NET Plattform nur für seine eigene Produktlinie Windows anbietet. Eine Laufzeitumgebung für das Betriebssystem Linux (und Derivate) steht aber in Form des Mono-Projekts in Aussicht, das vom Hersteller Ximian begonnen wurde. Nur lizenzrechtliche Probleme könnten zum Scheitern dieser Portierung führen.
Was C# von Java und C++ abhebt, ist die Tatsache, dass sowohl Klassen als auch Datentypen, wie in Smalltalk, durch Objekte repräsentiert werden. Ein weiterer Unterschied ist, dass in C# mit Attributen gearbeitet werden kann. Attribute erlauben es, einem Objekt Funktionalität hinzuzufügen, ohne seine Schnittstelle zu verändern. Man spricht hierbei auch von Metadaten.
Einige der Elemente von C++, die im allgemeinen als unsicher gelten, wie beispielsweise Zeiger-Arithmetik, wurden in C# nur für so genannten "unsafe code" (unmanaged code) erlaubt. Dieser benötigt eine veränderte Sicherheitseinstellung, um auf einem Zielsystem ausgeführt zu werden, und einen zusätzlichen Compiler-Schalter, um ihn zu übersetzen. Somit wird vermieden, dass sich versehentlich unsicherer Code in eine Anwendung einschleicht.
Sprachelemente
Zu Beginn der Klassiker aller Programme in C#:
|
Notationsregeln
Quellcode
Zeichensatz
Unicode
Schlüsselworte
abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while
if, elseif, else (Bedingte Ausführung)
|
for, while, do (Schleifen)
|
Die Bedingung der while-Schleife wird immer vor dem Anweisungsblock ausgeführt. Die Schleife durchläuft daher mindestens 0 mal.
|
Die Bedingung der do..while-Schleife wird immer nach dem Anweisungsblock ausgeführt. Die Schleife durchläuft daher mindestens 1 mal.
|
continue, break, goto
return, throw (Sprünge)
switch, case (Aufzählung)
Objekte und Klassen
Wenn man von einem Objekt spricht, handelt es sich dabei in der Umgangssprache normalerweise um ein reales Objekt oder einen Gegenstand des täglichen Lebens. Beispielsweise kann das ein Tier, ein Fahrzeug, ein Konto oder ähnliches sein.
Jedes Objekt kann durch verschiedene Attribute beschrieben werden und verschiedene Zustände annehmen und diese auch auslösen.
Übertragen auf die objektorierentierte Programmierung und C# ist ein Objekt die Instanz (siehe Schlüsselwort new
) einer Klasse. Eine Klasse kann man dabei als Bauplan oder Gerüst eines Objektes ansehen.
Eine Klasse besitzt Eigenschaften (Variablen) bzw. Attribute, Methoden (die Zustände/Tätigkeiten darstellen) und Ereignisse, die die folge von Zuständen sind bzw. diese auslösen.
Attribut(e) |
Methode(n) |
Ereignis(se) |
Die Klasse object
Die Klasse objekt ist ein Referenztyp, von dem jede Klasse automatisch abgeleitet wird. So kann durch explizite Typumwandlung jeder Typ in object
umgewandelt werden und umgekehtrt.
Da es in C# (noch) keine Templates gibt, (mit .net 1.2 werden diese eingeführt werden) wird object meistens genutzt, um Listen mit Objekten zu füllen. Diese werden vor dem einfügen in object
gecastet, eingefügt, und später, beim Bearbeiten wieder wieder zurückverwandelt. So muss man nicht für jede Klasse eine eigene Liste deklarieren.
Konstruktor
Destruktor
Das Schlüsselwort static
Das Schlüsselwort new
Das Schlüsselwort this
Schnittstellen (interface)
Strukturen (Struct)
Flags
Aufzählungstypen (Enumerationen)
Zugriffsmodifikatoren
Zugriffsmodifikatoren regeln den Zugriff auf Klassen und deren Mitglieder (Methoden, Eigenschaften, Variablen, Felder und/oder Ereignisse) in C#. Die folgende Tabelle führt die von C# unterstützten Zugriffsmodifikatoren auf und beschreibt deren Wirkung und den Sichtbarkeitskontext.
Name | Wirkung |
---|---|
internal |
|
private |
Beschränkt den Zugriff auf eine Klasse und deren Mitglieder. Eine mit |
protected |
Dieser Modifikator ist mit dem Modifikator |
public |
Auf als |
Hinweise:
- Standardmäßig sind Klassenmitglieder (Methoden, Eigenschaften usw.), denen kein Zugriffsmodifikator zugewiesen wurde, automatisch als
private
deklariert. Klassen selbst dagegen besitzen automatisch den Modifikatorinternal
und sind nur im aktuellen Namensraum (Namespace) sichtbar.
Wurde kein Namensraum zugewiesen, so gilt der sog. "global declaration space" als Standard-Namensraum.
- Die Modifikatoren können bis auf
protected
undinternal
nicht kombiniert werden.protected internal
spielt im Zusammenhang mit der Vererbung von Komponenten eine Rolle. Die Sichtbarkeit der beerbeten Klasse wird von der erbenden Klasse übernommen.
- Schnittstellen (interfaces) sind immer öffentlich definiert. Die Zuordnung eines Zugriffsmodifikators (mit Ausnahme von
public
) ist nicht zulässig.
Datentypen, Eigenschaften und Konstanten
C# kennt zwei Arten von Datentypen: Wertetypen (value types) und Referenztypen (reference types). Referenztypen dürfen dabei nicht mit Zeigern (pointer) gleichgesetzt werden, wie sie u. a. aus der Sprache C/C++ bekannt sind. Diese werden von C# zwar auch unterstützt, aber nur im unsicheren Modus (unsafe mode).
Wertetypen enthalten die Daten direkt, wobei Referenztypen im Gegensatz dazu nur Verweise auf die eigentlichen Daten, oder besser, Objekte darstellen. Bei Lesen und Schreiben von Wertetypen werden die Daten dagegen über einen Automatimus, Boxing genannt, in einer Instanz der jeweiligen Wrapper-Klasse gespeichert oder aus ihr geladen.
Die Zuweisung eines Wertes bzw. einer Referenz kann während der Deklaration erfolgen oder später, sofern die Variable nichts als Konstante deklariert wurde. Die Deklaration erfolgt durch Angabe eines Datentyps gefolgt von einem Variablennamen:
|
Es können auch mehrere Variablen des gleichen Typs zeitgleich deklariert werden:
|
Ferner besteht die Möglichkeit, der Variablen bei der Deklaration auch gleich einen Wert oder eine Referenz zuzuweisen (Initialwert):
|
Auch die Mehrfachzuweisung eines Wertes an verschiedene Variablen ist möglich:
|
Einen Sonderfall der Zuweisung stellt die Deklaration von Feldern (Arrays) dar. Näheres hierzu im entsprechenden Abschnitt.
Datentypen und Speicherbedarf
Datentyp | Bit | Vorz. | Wrapper-Klasse (struct type) |
---|---|---|---|
bool |
1 | - | System.Boolean
|
byte |
8 | J | System.Byte
|
char |
16 | - | System.Char
|
decimal |
128 | - | System.Decimal
|
double |
64 | - | System.Double
|
float |
32 | - | System.Single
|
int |
32 | J | System.Int32
|
long |
64 | J | System.Int64
|
sbyte |
8 | J | System.SByte
|
short |
16 | J | System.Int16
|
uint |
32 | N | System.UInt32
|
ulong |
64 | N | System.UInt64
|
ushort |
16 | N | System.UInt16
|
Datentypen sind in C# nicht elementar, sondern objektbasiert. Jeder der in der Tabelle aufgeführten Datentypen stellt einen Alias auf eine Klasse des Namespaces System dar. Beispielsweise wird der Datentyp bool
durch die Klasse System.Boolean
abgebildet. Man spricht dabei auch von einer Wrapper-Klasse.
Durch die Objektbasiertheit ist es möglich, Methoden auf Datentypen anzuwenden, die die entsprechende Wrapper-Klasse bereitstellt:
|
Vergleichbar mit C/C++, und anders als bei Java, gibt es unter C# vorzeichenbehaftete und vorzeichenlose Datentypen. Diese werden durch Voranstellen des Buchstaben s (signed) bei vorzeichenbehafteten Datentypen und durch Voranstellen des Buchstaben u (unsigned) bei vorzeichenlosen Datentypen symbolisiert (sbyte, uint, ulong, ushort,
mit Ausnahme von short
). Die Fließ- bzw- Gleitkomma-Datentypen (float, double, decimal
) können neben einfacher auch doppelte Genauigkeit aufweisen und haben einen variierenden Speicherbedarf.
Dadurch ändert sich die Genauigkeit, was in der Anzahl der möglichen Nachkommastellen zum Ausdruck kommt.
Konstanten (Schlüsselwort const)
Durch Verwendung des Schlüsselwortes const
wird einer Variablen ein konstanter Wert zugewiesen.
Einer mit const
deklarierten Variable kann nach der Deklaration und Wertzuweisung kein neuer
Wert bzw. keine neue Referenz zugewiesen werden. Die Variable wird als unveränderbare Konstante behandelt.
Eine Konstante kann dabei sowohl ein Wertetyp sein (also ein einfacher Datentyp), als auch ein Referenztyp,
der auf ein Objekt verweist. Das Schlüsselwort const
sichert dabei nur, dass die Referenz
nicht veränderbar ist, aber schützt nicht vor Änderungen am referenzierten Objekt. So kann beispielsweise einer
Konstanten die Referenz auf eine Liste zugewiesen werden, aber es sind weiterhin Änderungen an der Liste
selbst möglich (z. B. das Hinzufügen oder das Löschen von Listenelementen).
|
Das Schlüsselwort const
existiert auch in anderen Sprachen (z. B. C++) oder es existieren
vergleichbare Schlüsselworte (z. B. final
in der Programmiersprache Java oder PARAMETER
in Fortran).
Eigenschaften (Schlüsselworte get, set und value)
Eigenschaften (properties) sind Sichten auf öffentliche Variablen einer Klasse. Da es in der objektorientierten Programmierung schlechter Stil ist, Variablen public
zu deklarieren, weil somit unkontrolliert Wertänderungen durch Klasseninstanzen (Objekte) erfolgen können, bietet C# die aus VisualBasic bekannten Eigenschaften.
Die Variable selbst wird durch einen Zugriffsmodifizierer wie private
oder protected
(bei Variablen, die in abgeleiteten Klassen überschreiben werden sollen) für den Zugriff von außen gesperrt und über eine Eigenschaft zugänglich gemacht.
Über die Eigenschaft kann dann bestimmt werden, ob ein lesender oder schreibender Zugriff auf die referenzierte Variable erfolgen darf. Natürlich sind auch beide Möglichkeiten kombinierbar.
Eine Eigenschaft wird durch Zuweisung eines Datentyps (der dem Datentyp der Variable entsprechen muss) zu einem Eigenschaftsnamen angelegt und hat eine ähnliche Struktur wie die Syntax einer Methode. Die Eigenschaft ist dabei wie eine Variable ansprechbar und ihr kann auch ein Zugriffsmodifizierer zugewiesen werden. Eine Eigenschaft enthält aber selbst keine Daten, sondern bildet diese auf die referenzierte Variable ab (vergleichbar mit einem Zeiger).
Zur Abfrage einer Eigenschaft existiert in C# das Schlüsselwort get
und zum Setzen eines Wertes das Schlüsselwort set
. Von außen stellt sich die Eigenschaft dann wie eine Variable dar und der Zugriff kann entsprechend erfolgen (vgl. VisualBasic).
Die Programmiersprache Java verfolgt mit den Set- und Get-Methoden (Bean-Pattern, Introspection) das gleiche Ziel - alle Zugriffe erfolgen nie direkt über eine Variable, sondern über die entsprechende Methode (OOP, Sichtbarkeit).
Beispiel einer Eigenschaftsdefinition Wohnort
für eine private Variable (_wohnort
):
|
Durch das "Weglassen" des Schlüsselwortes set
oder des Schlüsselwortes get
kann gesteuert werden, ob die
Eigenschaft nur gelesen oder nur geschrieben werden darf. Das Schlüsselwort value
ist dabei ein Platzhalter für den der Eigenschaften zugewiesenen Wert, der gesetzt werden soll. Er kann nur in Verbindung mit dem Schlüsselwort set
im entsprechenden Block verwendet werden (und entspricht in etwa einer temporären lokalen Variable).
Beispiel für den Zugriff auf die oben definierte Eigenschaft Wohnort
:
|
Würde bei der oben gemachten Definition der Eigenschaft 'Wohnort' der get
-Block weggelassen, so würde
der lesende Zugriff zu einem Zugriffsfehler führen (im Beispiel in der Zeile, in der die Ausgabe erfolgt).
Neben dem einfachen Setzen oder Lesen einer Eigenschaft, können im set
-Block bzw. get
-Block
auch Operationen ausgeführt werden, beispielweise die Potenzierung eines bei set
übergebenen Wertes
(value
mal Exponent), bevor er der Variablen zugewiesen wird. Das gleiche gilt für das Schlüsselwort get
.
Theoretisch kann somit ein Zugriff für den Benutzer einer Klasse ganz unerwartete Ergebnisse bringen. Deshalb sollten alle Operationen, die Veränderungen auf einen Wert durchführen über normale Methoden abgebildet werden. Ausgenommen sind natürlich Wertprüfungen bei set
.
Das Beispiel konkateniert den der Eigenschaft übergebenen Wert (hier: Musterstadt) zur Zeichenkette "12345 ". Diese Aktion ist syntaktisch und semantisch richtig, aber sollte dennoch in einer Methode ausgeführt werden.
Die Klasse string
Escape-Sequenzen
Methoden
Parameter
Die Schlüsselworte in, out, ref
Parameterlisten
Rückgabewert
Indexer und Arrays (Felder)
Ereignisse und Delegate
Operatoren
Sichtbarkeit
Namensräume (Namespaces)
Schlüsselwort using
Vererbung
Abstrakte Klassen
Interfaces
Das Schlüsselwort override
Das Schlüsselwort base
Das Schlüsselwort wird im Zusammenhang von Vererbung genutzt. Es ist, vereinfacht gesagt, das für die Basisklasse, was this
für die aktuelle Klasse ist.
Nun folgt ein Beispiel, das die Verwendung von base
zeigt:
|
In diesem Beispiel wurde die Verwendung nur anhand des Basisklassenkonstruktors gezeigt. Wie in der Einleitung beschrieben kann base auch für den Zugriff auf die Member der Basisklasse benutzt werden. Die Verwendung erfolgt äquivalent zur Verwendung von this bei der aktuellen Klasse.
Das Schlüsselwort sealed
Der Modifizierer sealed
wird für sog. versiegelte Klassen benutzt. Das sind Klassen, von denen keine Ableitung möglich ist und die folglich nicht als Basisklassen benutzt werden können.
Bekanntester Vertreter dieser Art von Klassen ist die Klasse String
aus dem Namespace System
. (Zum Leidwesen vieler Programmierer, die diese Klasse gerne erweitern würden, und nun gezwungen sind, eine eigene Version von String
zu schreiben. Bitte beachten sie, dass sie Klassen, die sie mit sealed
"versiegelt" haben, vollständig sein sollten, da sie nicht erweitert werden können.
Casting (Konvertierung)
Weil C# eine typensichere Sprache ist, muss jede Variable einen Datentyp haben, dessen Wert sie aufnehmen kann. Da es manchmal nötig ist, Variablen zu konvertieren (d.h. ihren Typ zu verändern) gibt es das sog. Casting
.
Die Konvertierung wird in 2 Kategorien aufgeteilt:
-implizite Konvertierung
-explizite Konvertierung (Casting)
Von der impliziten Konvertierung bekommt man normalerweise nichts mit. Bei problemlos möglichen Konvertierungen (z.B. von int
nach long
) wird sie vom Compiler autom. durchgeführt.
Wenn jedoch z.B. Genauigkeitsverluste auftreten können (z.B. bei double
nach int
) müssen sie die Konvertierung selbst durchführen. Dies geschieht durch explizite Kovertierung:
|
Wie sie anhand des Beispiels sehen können, werden Castings immer mit (Dateityp)
ausgeführt.
Neben dem Casting gibt es auch sog. Boxing. Es bezeichnet die Umwandlung zwischen Wert- und Referenztypen. Der Zieltyp wird wie beim Casting in Klammern vor den zu Konvertierenden Typen geschrieben.
Überladen vs Überschreiben
Mehrfachvererbung
Mehrfachvererbung wird in C# leider nur in Form von Interfaces unterstützt. Bei Klassen wird nur die Einfachvererbung unterstützt.
Interfaces in C# können mit den abstrakten Klassen von C++, die rein virtuelle Methoden besitzen verglichen werden. Mehr über Interfaces erfahren sie im Kapitel Interfaces.
An dieser Stelle ein Beispiel, wie die Mehrfachvererbung angewandt werden kann:
|
Für Informationen zur Implentierung von Interfaces lesen sie bitte das Kapitel Interfaces
Exception-Handling (Ausnahmen)
Assemblies
Attribute (Metadaten)
Shared Libraries (DLLs)
Kommentare und Dokumentation
In C# sind, wie in C, C++ und Java, sowohl Zeilen- als auch Blockkommentare zulässig.
Zeilenkommentare beginnen dabei mit zwei aufeinanderfolgenden Schrägstrichen (//) und enden in der gleichen Zeile mit dem Zeilenumbruch. Alles was nach den Schrägstrichen folgt, wird bis zum Zeilenende als Kommentar angesehen und vom Compiler übergangen.
Blockkommentare, die sich über mehrere Zeilen erstrecken können, beginnen mit der Buchstabenkombination /* und enden mit */.
Sowohl Zeilen- als auch Blockkommentare können zu Beginn, aber auch mitten in einer Zeile beginnen. Blockkommentare können in der selben Zeile enden und es kann ihnen Sourcecode folgen, der vom Compiler ausgewertet wird. Alles was innerhalb des Blockkommentars steht wird vom Compiler übergangen.
|
Hinweis: Es sind auch Kommentare innerhalb eines Befehls, z. B. zur Kommentierung einzelner Methodenparameter möglich. Diese Art von Kommentaren sollte aber aus Gründen der Lesbarkeit und Wartbarkeit vermieden werden. Zur Dokumentation von Methoden stellt C# in Form von Metadaten (Attribute) einen Mechanismus bereit, der es ermöglicht, eine XML-basierte Dokumentation erzeugen zu lassen.
Verfügbare Klassenbibliotheken
- Collection
- Threads
- Reflection
- CodeDOM
- ADO.NET
- ASP.NET
- Windows.Forms
Verfügbarkeit (IDEs)
Neben der von Microsoft favorisierten Entwicklungsplattform VisualStudio.NET aus dem eigenen Hause, gibt es inzwischen auch Entwicklungsumgebungen (IDEs) anderer Hersteller für C#:
- C#-Builder von Borland
- Open Source-IDE SharpDevelop ( http://www.icsharpcode.net/OpenSource/SD/Default.aspx ).
Weblinks
- [1] Tutorial zur Programmiersprache C#. Enthält eine strukturierte Referenz aller Befehle und Schlüsselwörter.