Allgemeines zu C# 2.0
Der Name C# stammt aus der Welt der Musik und bezeichnet einen Ton -
im deutschen Sprachraum "Cis", also die Erhöhung des Tons "C" um einen
Halbton. Ausgesprochen wird er "see sharp".
Die objektorientierte Hochsprache wurde von Microsoft unter dem Entwickler
Anders Hejlsberg (bekannt als Chefentwickler von Delphi) entworfen.
Sie liegt aktuell in der Version 2.0 vor.
Die Version 3.0, dessen endgültiges Release für Ende 2007 geplant ist,
ist aktuell als fast fertige Preview-Version im sog. LINQ-Project
(Language Integrated Query)
auf der offiziellen Homepage von Microsoft
erhältlich. (Stand Ende 2006)
Anhand eines Vergleiches mit der verwandten Sprache Java, zu der C# ja
eine Konkurrenzsprache von Microsoft darstellen soll, folgt nun eine kleine
Einführung in die Sprache C# in der Version 2.0.
top
Ähnlichkeiten zwischen C# und Java
- nahezu identische Syntax
-
Objektorientierung: eine Klasse kann von einer
anderen Klasse erben, aber von mehreren
Interfaces
-
Typsicherheit: Zeigerarithmetik, sowie inkompatible Zuweisungen und
Typkonversionen werden zur Compile-Zeit abgefangen (es sei denn, ein
Block wird explizit als
unsafe deklariert), weiterhin
wird zur Laufzeit sichergestellt, dass die Array-Indizes in ihren
erlaubten Grenzen liegen.
- Garbage Collection
-
Klassen liegen in Namensräumen (Java:
Package ,
C#: namespace )
- Thread-Programmierung
- Generizität (generische Typen)
- Reflection: Ermittlung von Typinformationen zur Laufzeit
-
Attribute: Anhängen von Informationen an eine Klasse; Abfragen
über Reflection
-
Bibliotheken: Die Typen und auch Methoden sind denen von Java nachempfunden.
top
Unterschiede zwischen C# und Java
Auch wenn Java und C# sich sehr ähnlich sind, gibt es doch kleinere Unterschiede,
die wir im Folgenden betrachten werden.
top
foreach-Schleife
C# bietet die Möglichkeit über die sog. foreach -Schleife,
über alle Elemente, die das Interface IEnumerable<T>
implementieren, wie z.B. Arrays, zu iterieren:
int[] ia = new int[] {1, 3, 7, 2};
foreach(int i in ia)
Console.WriteLine(i);
Darüberhinaus, kann man auch über eine selbstgeschriebene Klasse "iterieren".
Dazu muss in dieser eine Methode namens "GetEnumerator " vom
Typ "IEnumerator<T> " exisiteren. Die einzelnen Werte, auf
die man dann innerhalb der foreach -Schleife, werden jeweils
über yield return -Anweisungen generiert. Der Wert der ersten
ist im ersten Schleifendurchlauf der Wert der Laufvariablen, der Wert der zweiten
Anweisung ist der Wert der Laufvariablen um zweiten Durchlauf, etc.
Ein yield break führt zu einem Abbruch der Enumerationsmethode.
Man kann sich auch flexiblere Iteratoren erstellen, die einen eigenen Namen
und eine Parameterliste haben. Diese haben einen selbst zu wählenden Namen,
sowie eine (evtl. auch leere) Parameterliste. Diese sind jedoch vom Typ
IEnumerable<T> .
Dabei ist zu beachten, dass auf die Laufvariable nur lesend zugegriffen
werden darf.
top
Parameterübergabe
C# stellt 3, bzw. 4 verschiedene Parameterübergabemöglichkeiten zur
Verfügung:
-
Call-by-Value: Die Standard-Übergabeart übergibt nur den Wert, eine
Änderung des Wertes hat "nach außen" keine Wirkung.
-
Call-by-Reference: Es wird nicht der Wert, sondern die Referenz übergeben.
Man kann also keine konstanten Werte übergeben. Eine Änderung des Wertes
innerhalb der Methode verändert auch den Wert der Variablen des aktuellen
Parameters.
Sowohl der aktuelle als auch der formale Parameter müssen jeweils mit
dem Schlüsselwort "ref " gekennzeichnet.
Vor der Übergabe muss der aktuelle Parameter initialisiert sein.
-
Out-Parameter: Entspricht dem Konzept Call-by-Reference mit dem
Unterschied, dass der aktuelle Parameter nicht zwingend initialisiert
sein muss. Der formale Parameter muss aber in jedem Fall mit einem Wert
belegt werden.
Sowohl der aktuelle, als auch der formale Parameter werden mit dem
Schlüsselwort "out " gekennzeichnet werden.
-
Variable Parameteranzahl: Kennzeichnet man den letzten formalen
Parameter mit dem Schlüsselwort "
params " und ist dieser
ein eindimensionales Array, so kann man als aktuellen Parameter dort
entweder ein entsprechendes Array übergeben, oder eine Liste von Werten
des entsprechenden Basistypen.
top
Blockmatrizen
Es gibt 2 Möglichkeiten, mehrdimensionale Arrays im Speicher abzulegen:
- rechteckige Arrays: liegen als kompakter Block im Speicher
-
jagged ("ausgefranste") Arrays: enthalten als Elemente Referenzen
auf weitere Arrays
top
einheitliches Typsystem
In C# werden alle Datentypen von Object abgeleitet und erben dessen Methoden.
top
goto-Anweisung
Die berühmt-berüchtigte goto -Anweisung wurde in den
Sprachumfang wieder aufgenommen, allerdings unter strengen Restriktionen:
- Zwar darf man aus einem Block herausspringen aber nicht in einen hinein
- Der Aussprung aus einem
finally -Block ist verboten
top
Versionierung
Wie bereits im .NET-Abschnitt erwähnt, kann eine
Bibliothek in mehreren Versionen vorliegen. Welche verwendet werden soll,
kann man über die Attribute festlegen.
top
Properties
Über Properties (auch "smart fields" genannt) kann man auf Felder zugreifen,
ohne dass man explizit auf diese zugreift. Dazu kann man innerhalb der
Properties je eine get - und/oder set -Methoden definieren:
String name;
String Name{
get{ return name; }
set{ name = value; }
}
Wenn man sich nun ein Objekt der Klasse erzeugt, in dem eine solche Property
deklariert ist, kann man diese Property wie eine Variable nutzen. Das in
obigem Beispiel verwendete "value " existiert in der set -Methode
und enthält den übergebenen Wert, wenn auf die Property schreibend
zugegriffen wird. Ein Beispielaufruf unter der Annahme, dass "foo "
ein Objekt enthält, in der obige Properties enthalten sind sähe wie folgt aus:
foo.Name = "Simone Young";
Console.WriteLine(foo.Name);
top
Delegates
Ein Delegate ist ein Methodentyp, der dazu dient, Variablen zu deklarieren,
in denen man eine oder mehrere Methoden speichern kann. In einer Instanz dieses
Delegate
delegate void d(String s);
kann man alle Methoden speichern, die einen void -Rückgabetyp
und eine Parameterliste mit einem String -Parameter aufbieten können:
void print(String s){Console.WriteLine(s);}
...
d del = new d(print);
del("Veronika Waldner");
Intern wird die Methode print("Veronika Waldner") aufgerufen.
"Addiert" man eine weitere Methode hinzu:
del += new d(print);
würden beide Methoden nacheinander mit dem selben Parameter aufgerufen werden,
wobei man hier jede beliebige Funktion zuweisen kann, die zu diesem
Delegate kompatibel ist.
Man kann einem Delegate auch eine anonyme Methode zuweisen, also eine,
die vorher nicht erst deklariert werden muss:
del = new d(delegate (String s){Console.WriteLine(s);});
Man beachte hier, dass man keinen Rückgabetyp angeben darf!
top
|