Einführung in C# 2.0

Das .NET-Framework

C# 2.0

  • Allgemeines
  • Ähnlichkeiten
  • Unterschiede
  • C# 3.0

    Fazit

    Quellen/Links

    Anfang

    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