1 C# (im Vergleich zu Java) IFC-Seminar 02.07.2001 Jan Kraneis [email protected] 2 1 Was ist C# 1.1 Die Definition von Microsoft: C# is a simple, modern, object oriented, and type-safe programming language derived from C and C++. C# (pronounced “C sharp”) is firmly planted in the C and C++ family tree of languages, and will immediately be familiar to C and C++ programmers. C# aims to combine the high productivity of Visual Basic and the raw power of C++. 1.2 Was ist es wirklich? • das werden wir in den nächsten Minuten herausfinden 1.3 Voraussetzungen für diesen Vortrag • Java-Kenntnisse 3 2 Ein kleines Beispiel 2.1 Hello World ..in Java class Hello { public static void main (String args []) { System.out.println("Hello, World!"); } } ..in C# class Hello { static void Main() { System.Console.WriteLine("Hello, {0}", "World!"); } } Unterschiede • Der erste Buchstabe der Methodennamen werden per Konvention groß schreiben. • Mehrere vollwertige public deklarierte Klassen pro Datei erlaubt. • Dateiname != Klassenname erlaubt. • Main kann verschiedene Signaturen haben: static static static static void Main() {...} void Main(String[] args) {...} int Main() {...; return errorcode;} int Main(String[] args) {...; return errorcode;} 2.2 Ausführung c:\> csc hello.cs Microsoft (R) Visual C# Compiler Version 7.00.9254 [CLR version v1.0.2914] Copyright (C) Microsoft Corp 2000-2001. All rights reserved. • Quelldatei ist nun in die MSIL (Microsoft Intermediate Language) übersetzt. c:\> hello.exe Hello, World! c:\> • Zum Ausführen werden die Bibliotheken der CLR (Common Language Runtime) benötigt. 4 2.3 Namespaces • Namespace-Deklarationen umschließen die Klassen. • Namespaces können ineinander geschachtelt werden oder mit Punkt getrennt werden. • Jede Quelldatei kann beliebig viele Namespaces definieren. • Funktion wie package in Java. namespace Mein.Eigener.Namespace { class A { ... } } 2.3.1 Die using Klausel • Ähnlich import in Java Beispiele: using System; using System.Collections; using MyHashTable=System.Collections.HashTable; nicht aber: using System.Collections.Hashtable; • Unterschied: Einzelne Klassen kann man nur mit einem Alias angeben. 5 3 Common Language Runtime (CLR) • Laufzeitumgebung für .NET Applikationen. • Vergleichbar mit der Virtual Machine von Java. • In Java: Cross Platform Development. • .Net: Cross Language Development. • Eine Klassenbibliothek für alle unterstützten Sprachen (C#, C++, Visual Basic, JScript). • Klassen aus jeder dieser Sprachen können Basisklassen für Klassen einer anderen Sprache sein. • Quellen werden in Bytecode übersetzt, und auf der CLR ausgeführt. • Sicherheitsmodell. 6 4 Grundlegende Datentypen und Klassen 4.1 Grundlegende Datentypen Die grundlegenden Datentypen in C# Typ byte sbyte short ushort int uint long ulong float double decimal string char bool Byte 1 1 2 2 4 4 8 8 4 8 8 String Char Boolean Laufzeittyp Byte SByte Int16 UInt16 Int32 UInt32 Int64 UInt64 Single Double Deciaml Unicode-Zeichenfolge Unicode-Zeichen Boolscher Wert Beschreibung Byte-Wert ohne Vorzeichen Byte-Wert mit Vorzeichen Short-Wert mit Vorzeichen Short-Wert ohne Vorzeichen Integer-Wert mit Vorzeichen Integer-Wert ohne Vorzeichen Langer Integer-Wert mit Vorzeichen Langer Integer-Wert ohne Vorzeichen Gleitkommazahl Gleitkommazahl doppelte Genauigkeit Zahl mit fester Genauigkeit • Die fett geschriebenen Typen haben keine Pendant in Java. • Die anderen Typen entsprechen (bis auf die Schreibweise) denen in Java. 4.1.1 Verweistypen und Wertetypen • Wertetypen werden dem Stack zugeordnet oder strukturintern zugewiesen. + Typischer Wertetyp: int. • Verweistypen sind Heaps zugeordnet. + Typischer Verweistyp: string. • Beide Typen werden von object abgeleitet. • Boxing: Soll ein Wertetyp als object fungieren, wird ein Wrapper, der das Werteobjekt als Verweisobjekt erscheinen läßt, dem Heap zugewiesen. Der Wert des Wertetyps wird kopiert. • Unboxing: Der umgekehrte Vorgang zum Boxing. 4.2 Arrays • Index beginnt für alle Arraytypen bei 0. 7 4.2.1 Eindimensional Initialisierung: Erlaubt: int[] i = new int[17]; string[] names = {"Horst", "Fritz", "Max"}; string[] names2 = new string[3] {"Horst", "Fritz", "Max"}; Nicht erlaubt: int i[] = new int[17]; Zugriff: i[3] = 42; System.Console.WriteLine(names[2]); 4.2.2 Mehrdimensionale Arrays Initialisierung: int[,] matrix = new int[5,2]; int[,] matrix2 = {{1,2}, {3,4}, {5,6}, {7,8}}; Zugriff: matrix[0,0] = 5; System.Console.WriteLine(matrix2[3,1]); 4.2.3 Unregelmäßige Arrays Initialisierung: int[][] matrix = new int[3][]; matrix[0] = new int[10]; matrix[1] = {10, 20, 30}; int[][] matrix2 = { new int[] {1, 2, 3}, new int[] {4}, new int[] {5, 6, 7, 8, 9} }; Zugriff: matrix[0][5] = 356; System.Console.WriteLine( matrix2[2][4] ); 4.3 Datentyp Decimal • Wird intern mit 128 Bit repräsentiert. • Hohe Genauigkeit (bis 28 Nachkommastellen). • Kleiner Bereich: 1.0 × 10-28 bis 7.9 × 1028. 8 4.4 Konstanten • Konstanten werden mit dem Schlüsselwort const markiert. • In Java: final. 4.5 Die Klasse object • Basisklasse aller Klassen. • Besitzt gleiche Methoden wie java.lang.Object, nur anders buchstabiert. • clone() vs. MemberwiseClone(). • finalize() vs. Finalize(). • toString() vs. ToString(). • etc. 9 5 Spracheigenschaften 5.1 Klassen, Strukturen und Schnittstellen • Das Schlüsselwort class wird zum Deklarieren eines Verweistypen verwendet. + wie in Java. • Das Schlüsselwort struct wird zum Deklarieren eines Wertetypen verwendet. + kein Java-Äquivalent. • C# und die CLR bieten keine Unterstützung für Mehrfachvererbung. • Man kann mehrere Schnittstellen implementieren (Schlüsselwort interface). 5.2 Accessmodifier Java public protected package private ? C# public protected internal internal private (default) protected 5.3 Vererbung • Statt extends und implements wird nur der : benutzt. • Man kann mehrere Schnittstellen implementieren. • Aufruf der Basisklasse mit base.Methode(). • Konstruktor der Basisklasse wird im Konstruktorkopf aufgerufen. • Beispiel: Inheritance.cs. 5.4 Virtuelle Methoden • Java: Per Default können alle Methoden überschrieben werden. • C#: Überschreibbare Methoden müssen mit dem Schlüsselwort virtual gekennzeichnet werden. • Die überschreibende Methode muss mit dem Schlüsselwort override gekennzeichnet werden. 5.5 Abstrakte Klassen • Wie in Java. 10 5.6 sealed Klassen • sealed entspricht dem Schlüsselwort final für Klassen in Java. 5.7 Verschachtelte Klassen • Syntax wie bei Memberklassen in Java. • Verhalten wie Toplevel nested class in Java. • Accessmodifier wie in Java. • Interfaces und abstrakte Klassen erlaubt. • Zugriff wie in Java: Nested.cs. 5.8 Enumerations • einfaches Aufzählen von konstanten Werten. • erlaubte Typen: enum AllowedTypes:short { BYTE, SBYTE, SHORT, USHORT, INT, UINT, LONG, ULONG } • Defaulttyp ist int. • Die Initialisierung startet defaultmäßig bei 0; +1 für jedes Element. • Berechnete Werte bei der Initialisierung sind erlaubt. 5.9 Operatoren • Die Operatoren in C# gleichen den Operatoren in Java bis auf: + >>>. • Alle binären Operatoren sind linksassoziativ bis auf: + Zuweisungsoperatoren. + ?:-Operator. 5.9.1 Rangfolge der Operatoren • Wie in Java. 11 5.9.2 Typenoperatoren • typeof gibt den Typ des Objekts zurück (eine Instanz der Klasse System.Type). • is ist äquivalent zu instanceof. • as prüft wie is und konvertiert in den entsprechenden Typen. + Rückgabewert ist der konvertierte Typ oder null. 5.9.3 Operatorüberladung • Operatoren können für Klassen und Strukturen definiert werden. public static MyObject operator -(MyObject myobject) { return (new MyObject(-myobject.value)); } public static MyObject operator +(MyObject left, MyObject right) { return (new MyObject(right.value + left.value)); } • Ob man intern von links oder rechts auswertet, ist egal. • Einschränkungen: &&, ||, ?:, += und *= können nicht überladen werden. 5.10 Anweisungen Wenn nicht anders gesagt, sind die Anweisungen wie in Java. 5.10.1 Auswahlanweisungn • if. • switch: + am Ende eines case muß break oder goto case ... stehen. 5.10.2 Wiederholungsanweisungen • while. • do - while. • for. • foreach erlaubt den Durchlauf enumerierbarer Typen: + break und continue erlaubt. + Die Inhalte des zu durchlaufenden Containers können nicht geändert werden. 5.10.3 Sprunganweisungen • break. • continue. 12 • goto. • return. 5.10.4 Lockanweisung • lock(x) {...} entspricht synchronized(x) {...} in Java. 5.11 Properties • Sehen nach außen wie Instanzvariablen aus. • Werden durch eine Art Methoden implementiert: class A { private int x; public int X { get {return x;} set {x = value;} } } • Durch Weglassen von set erhält man eine readonly-property. • C#: direkte Sprachunterstützung. • In Java: nur Namenskonvention. 5.12 Indizierer • Zugriff auf Objekte wie auf einen Array. • Syntax ähnlich der von Properties: class A { ... private ArrayList al; //beinhaltet den Zustand ... public object this[int index] { get { return(al[index]); } set { al[index] = value; } } } 5.13 Delegates • Delegates treffen Festlegung zwischen einer aufrufenden und einer implementierenden Komponente. • Schlüsselwort delegate. • Delegates werden zur Laufzeit erstellt (vs. Interfaces zur Compilezeit). 5.14 Events • Events benachrichtigen andere Klassen über ein aufgetretenes Ereignis. 13 • Schlüsselwort event. • Beispiel: DelegatesNEvents.cs. 5.15 Attribute • Attribute sind Anmerkungen, die für Elemente des Quellcodes gesetzt werden. [Serializable] class A { ... [NonSerialized] private Hashtable followSet; ... } 5.15.1 Eigene Attribute • Man kann eigenen Attributklassen entwerfen. 5.16 Reflection und Metadata • Metadaten zur Klasseninformation werden in den Bytecode geschrieben, was Reflection ermöglicht: + Typenidentifikation. + Dynamische Methodenaufrufe. + Serialisierung. 5.17 Parameter • Defaultmäßig sind Parameter in C# Werteparameter (call by value). 5.17.1 Referenzparameter • C# unterstützt call by reference. • Das Schlüsselwort ref markiert die Parameter im Methodenkopf und im Aufruf. class A { public static void foo(ref int a, ref int b) {...} static void Main() { int a=0, b=1; foo(ref a, ref b); } } • Markiert man die Parameter im Aufruf mit out, müssen die Variablen nicht initialisiert werden. 5.18 Präprozessor • Es stehen teilweise die Funktionen des C/C++- Präprozessors zu Verfügung bis auf: + #include-Dateien. 14 + Textersetzung mit #define. • Erlaubt sind: + #define (Bezeichner), #undef (Bezeichner), #if (Ausdruck), #elif (Ausdruck), #else, #endif, #warning, #error, ... 5.19 Exceptions • Exceptions sind in C# aufgebaut wie in Java, bis auf: + Kein throws und kein Zwang, Exceptions zu behandeln. 5.20 Unsicherer Code • Schlüsselwort unsafe markiert Methoden in denen man C-Code und C-Pointer nutzen darf. • Keine Typensicherheit. • Nur in besonderen Fällen schneller, als Systemaufrufe. 5.21 Kommentare • Alle Javatypischen Kommentare werden als Kommentare erkannt 5.21.1 Kommentare in XML • Starten mit ///. • Vordefiniertes Schema. Erlaubte Elemente: Element Beschreibung <summary> <remarks> <c> <code> <example> <exception> <list> <param> <paramref> <permission> <returns> <see cref="member"> Eine kurze Beschreibung eines Elements Eine ausführliche Beschreibung eines Elements Formatzeichen als Code innerhalb eines anderen Textes Mehrzeiliger Codeabschnitt - üblicherweise in <example> Ein Beispiel zur Verwendung (Klasse | Methode) Die von einer (Klasse | Methode) geworfenen Exceptions Eine Liste von Elementen Beschreibt einen Parameter für eine Mitgliedsfunktion Ein Verweis auf einen Parameter in einem anderen Text Die auf ein Mitglied angewandte Berechtigung Der Rückgabewert einer Methode Eine Verknüpfung zu einem Mitglied oder Feld in der aktuellen Kompilierungsumgebung <seealso cref="member"> Eine Verknüpfung im "Siehe auch"-Abschnitt der Dokumentation <value> Beschreibt den Wert einer Property • Beispiel: DelegateNEvent.cs. 15 5.22 Weitere Syntaxeigenschaften und "Features" • Methoden und Variablen müssen verschieden benannt werden. • Kein Äquivalent zu Java-Properties. • Test.cs. 16 6 Werkzeuge • .Net Developer Framework. • Visual Studio .Net. 17 7 Fazit • C# ist Java sehr ähnlich. • Bei Portierungen von Java nach C# sollte man folgendes beachten: + Aufrufe der Klassenbibliothek. + Keine elegante Form der Inneren Klasse. + Interface wird zum Attribut (Serialisierung). • "C# is not a Java-clone() but a MemberwiseClone()!"