380 likes | 512 Views
Softwareentwicklung mit .NET Teil 2 Einführung in C# Dr. Ralph Zeller. Einleitung . Viele Entwickler wünschen sich eine Programmiersprache, die so einfach ist wie Visual Basic und so mächtig und flexibel wie C++ C# ist die beste Wahl für das .NET Framework Ideal für .NET Applikationen
E N D
Softwareentwicklung mit .NET Teil 2 Einführung in C# Dr. Ralph Zeller
Einleitung • Viele Entwickler wünschen sich eine Programmiersprache, die • so einfach ist wie Visual Basic und • so mächtig und flexibel wie C++ • C# ist die beste Wahl für das .NET Framework • Ideal für • .NET Applikationen • Web Services • ...
C# Designziele • Erste C/C++ ähnliche komponenten-orientierte Sprache • Garbage Collection • Keine Speicherlecks oder „wilde Pointer“ • Exceptions • Error Handling von Anfang an bedacht • Typsicherheit • Keine uninitialisierten Variablen • Keine unsichere Casts
C# Programmstruktur • Namespaces • Enthalten Typdefinitionen und Namespaces • Typdefinitionen • Klassen, Strukturen, Interfaces, ... • Elemente von Typen • Konstanten, Felder, Methoden, Properties, Indexer, Events, Operatoren, Konstruktoren, Destruktoren • Organisation der Dateien • Keine Header-Dateien, Programmcode ist “in-line” • Die Reihenfolge der Deklarationen ist ohne Bedeutung
C# Program Struktur using System; namespace System.Collections { public class Stack { Entry top; public void Push(object data) { top = new Entry(top, data); } public object Pop() { if (top == null) throw new InvalidOperationException(); object result = top.data; top = top.next; return result; } } }
Statements und Expr. • If, while, do benötigen eine boolsche Bedingung • Mit goto kann nicht in Blöcke gesprungen werden • Switch Statement • Kein “fall-through“ im Switch Statement • “break”, “goto case” or “goto default” notwendig • Checked und unchecked Statement • Ausdrücke müssen etwas tun if (value == 0) //ok WriteLine("true"); if (value) //Fehler WriteLine("true");
Foreach Statement • Iteration von Arrays • Iteration durch selbst definierte Collections public static void Main(string[] args) { foreach (string s in args) Console.WriteLine(s); } foreach (Customer c in customers.OrderBy("name")) { if (c.Orders.Count != 0) { ... } }
Zwei Arten von Typen 123 i int i = 123; string s = "Hello world"; "Hello world" s 123 j int j = i; string t = s; t
} “Boxing” } “Unboxing” Boxing und Unboxing • Jeder Datentyp kann als Objekt gespeichert oder übergeben werden int i = 123; object o = i; int j = (int)o; 123 i 123 o System.Int32 123 j
Selbst definierte Typen • Classes (reference) • Wird für die meisten Objekte verwendet • Structs (value) • Für Daten-Objekte (Point, Complex, etc.). • Interfaces
Classes and Structs class CPoint { int x, y; ... } struct SPoint { int x, y; ... } CPoint cp = new CPoint(10, 20); SPoint sp = new SPoint(10, 20); 10 sp 20 cp 10 20 CPoint
Klassen (class) • Einfachvererbung (single inheritance) • Implementierung von beliebig vielen Interfaces • Elemente einer Klasse • Konstanten, Felder, Methoden, Operatoren, Konstruktoren, Destruktoren • Properties, Indexer, Events • Verschachtelte Typen • Statische Elemente (static) • Zugriffsschutz • public, protected, internal, private
Strukturen (struct) • Sind immer “value types“ • Ideal für “kleine” Objekte • Keine Allokierung auf dem Heap • Weniger Arbeit für den Garbage Collector • Effizientere Speicherbenutzung • Benutzer können “primitive” Typen selbst erzeugen • Syntax und Semantik sehr eingängig • Operator Overloading, Conversion Operators • .NET Framework nutzt diese auch • int, float, double, … sind alles structs
Interfaces • Enthalten Methoden, Properties, Indexer, und Events • Explizite Implementierung möglich • Löst Interface Probleme bei Namenskollisionen • Ausblenden der Implementierung vor dem Benutzer interface IDataBound { void Bind(IDataBinder binder); } class EditBox: Control, IDataBound { void IDataBound.Bind(IDataBinder binder) {...} }
Vererbung • Methoden sind standardmäßig NICHT virtual • Eine Methode kann nur mit „override“ überschrieben werden class B { public virtual void foo() {} } class D : B { public override void foo() {} }
Vererbung • Methoden sind standardmäßig NICHT virtual • Überschreiben einer nicht-virtual Methode Compilerfehler!Außer man verwendet „new“ class N : D { public new void foo() {} } N n = new N(); n.foo(); // call N’s foo ((D)n).foo(); // call D’s foo ((B)n).foo(); // call D’s foo
Parameterübergabe • inParameter: Entspricht einer Übergabe „ByVal“. Es wird der Wert an die Methode übergeben static void Foo(int p) {++p;} Static void Main() { int x = 8; Foo(x); // Kopie von x wird übergeben Console.WriteLine(x); // x = 8 }
Parameterübergabe • refParameter: Man übergibt die Referenz an die Methode static void Foo(ref int p) {++p;} Static void Main() { int x = 8; Foo(ref x); // Referenz von x wird übergeben Console.WriteLine(x); // x = 9 }
Parameterübergabe • outParameter: Erhält einen Wert von Methode zurück (Variable muss vorher nicht initialisiert werden) static void Foo(out int p) {p = 3;} Static void Main() { int x; Foo(out x); // x ist bei Übergabe nicht initialisiert Console.WriteLine(x); // x = 3 }
Komponentenentwicklung • Was macht eine Komponente aus? • Properties, Methoden, Events • Design-Time und Run-Time Information • Integrierte Hilfe und Dokumentation • C# hat die beste Unterstützung • Keine “naming patterns“, Adapter, ... • Keine externen Dateien • Komponenten sind einfach zu erstellen und zu verwenden
Properties • Eine Mischung aus Feldern und Methoden (= smart fields) • Properties sind: • für Read-Only Felder • für Validierung • für berechnete oder zusammengesetzte Werte • Eine Ersatz für Felder in Interfaces
Properties Beispiel public class Button: Control { private string caption; public string Caption { get { return caption; } set { caption = value; Repaint(); } } } Button b = new Button(); b.Caption = "OK"; String s = b.Caption;
Indexer • Praktische Möglichkeit, Container zu implementieren • Erweitern die Idee der Properties (= smart properties) • Erlauben Indexierung von Daten innerhalb des Objekts • Zugriff ist wie bei Arrays • Der Index selbst kann von jedem Datentyp sein a = myDict["ABC"];
Indexer Beispiel public class ListBox: Control { private string[] items; public string this[int index] { get { return items[index]; } set { items[index] = value; Repaint(); } } } ListBox listBox = new ListBox(); listBox[0] = "hello"; Console.WriteLine(listBox[0]);
Delegates • Ein Delegate Objekt repräsentiert eine Funktion.Dadurch kann ein Delegate als Funktionsparameter oder Mitglied einer Klasse fungieren. • Ersatz für C++ Funktionspointer • Objektorientiert, type-safe und sicher • Grundlage für Events
Delegates Beispiel using System; delegate void Delg(string sTry); public class Example1{ // function which uses the delegate object private static void Func1(Delg d){ d("Passed from Func1"); } // function which is passed as an object private static void Func2(string sToPrint){ Console.WriteLine("{0}",sToPrint); } // Main execution starts here public static void Main(){ Delg d = new Delg(Func2); Func1(d); } }
Attribute • Runtime / Design-Time Informationen für Typen und deren Elemente • Beispiele // Klasse serialisierbar machen [Serializable] class MyClass { … } // Security Einstellungen [assembly:EnvironmentPermissions( SecurityAction.RequestRefuse, UnmanagedCode = true)] namespace Perms { class ReadConfig { … } }
Attribute • Für Typen und deren Elemente • Zugriff zur Laufzeit über “reflection“ • Vollständig erweiterbar • Ein Attribut ist eine Klasse, die von System.Attribute abgeleitet wurde • Wird im .NET Framework oft benutzt • XML, Web Services, Security, Serialization, Component Model, COM und P/Invoke Interop …
Beispiele Attribute • Attribute sind Klassen • Abgeleitet von System.Attribute • Klassenfunktionalität = Attributfunktionalität public class HelpUrlAttribute : System.Attribute { public HelpUrlAttribute(string url) { … } public string Url { get {…} } public string Tag { get {…} set {…} } }
Attribut verwenden • Wenn der Compiler ein Attribut sieht • ruft er den Konstruktor auf und übergibt die Argumente • falls weitere Parameter existieren, setze er das Property auf den entsprechenden Wert • speichert die Parameter in den Metadaten [HelpUrl("http://SomeUrl/MyClass")] class MyClass {} [HelpUrl("http://SomeUrl/MyClass", Tag="ctor")] class MyClass {}
Attribute abfragen • Mittels Reflection können Attribute abgefragt werden Type type = typeof(MyClass); foreach(object attr in type.GetCustomAttributes() ) { if ( attr is HelpUrlAttribute ) { HelpUrlAttribute ha = (HelpUrlAttribute) attr; myBrowser.Navigate( ha.Url ); } }
XML Kommentare • Konsistente Art, um Dokumentation aus dem Code zu erzeugen • "///" Komentare werden exportiert • Dokumentation wird vom Compiler durch /doc: extrahiert werden • Ein „kleines“ Schema ist eingebaut
Bsp. XML Kommentare class XmlElement{ /// <summary> /// Returns the attribute with the given name and /// namespace</summary> /// <param name="name"> /// The name of the attribute</param> /// <param name="ns"> /// The namespace of the attribute, or null if /// the attribute has no namespace</param> /// <return> /// The attribute value, or null if the attribute /// does not exist</return> /// <seealso cref="GetAttr(string)"/> /// public string GetAttr(string name, string ns) { ... } }
C# und Pointer • C# unterstützt • Eingebauter Typ: String • Benutzerdefinierte Referenztypen • Große Auswahl an Collection-Klassen • Referenz- und Ausgabeparameter (out , ref) • 99% der Pointer werden nicht mehr benötigt • Dennoch sind Pointer verfügbar, wenn Programmcode mit unsafe markiert ist
Beispiel unsafe Code class FileStream: Stream { int handle; public unsafe int Read(byte[] buffer, int index, int count) { int n = 0; fixed (byte* p = buffer) { ReadFile(handle, p + index, count, &n, null); } return n; } [DllImport("kernel32.dll", SetLastError=true)] static extern unsafe bool ReadFile(int hFile, void* lpBuffer, int nBytesToRead, int* nBytesRead, Overlapped* lpOverlapped); }
Uff... Fragen?