Contenu connexe
Similaire à 2005 - .NET SummerCamp: C# 2.0 (20)
Plus de Daniel Fisher (20)
2005 - .NET SummerCamp: C# 2.0
- 1. Copyright © 2005 newtelligence® AG. All rights reserved
Daniel Fisher
Software Engineer, newtelligence® AG
danielf@newtelligence.com
.NET Fundamentals
Neues in C# 2.0
- 2. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Agenda
Neuerungen in C# 2.0
Generische Datentypen
•Einführung
•Programmierung
•Anwendung
•Generische Klassen in .NET
Iteratoren
Anonyme Methoden
Partielle Klassen
Sonstige Erweiterungen in C# 2.0
Kompatibilität zu C# 1.0
Zusammenfassung
- 3. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Neuerungen in C# 2.0
C# ist gegenüber der alten Version erweitert worden
Die Programmiersprache als solches hat sich aber nicht
geändert
•Wir müssen nicht umlernen
•Wir müssen nur dazulernen
Größtes Feature in C# 2.0:
•Generische Typen
•Für die Template-Anhänger der C++-Gemeinde ein
wichtiger Punkt
•Für VB.NET, C#, C++/CLI
- 4. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Generische Datentypen
Generische Typen machen es möglich, dass Klassen,
Strukturen, Interfaces, Delegates und Methoden
passend zum Typ der Daten, die sie verwalten sollen,
erzeugt werden.
Einfaches Beispiel: Sortierung
•Man kann int, string, double, ... sortieren
•Mit generischen Typen schreibt man nur eine Sortierungs-
Methode
•Diese kann dann mit den unterschiedlichen Typen
„angewendet“ werden
- 5. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Einführung
Warum braucht man generische Typen?
•Die Standard-Collection-Klassen speichern die Daten
immer als object
•Beim Auslesen der Daten muss explizit gecastet werden
Da können Fehler passieren evtl. erst zur Laufzeit
Kostet Performance (Boxing, Unboxing, Typprüfung)
Beispiel: Stack-Collection
Stack stack = new Stack();
stack.Push(3);
int i = (int)stack.Pop();
- 6. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Programmierung
Erstellung einer Klasse mit einem sogenannten „Typenparameter“
•Wird in spitzen Klammern angegeben
•Wird wie ein normaler Typ benutzt
Beispiel: Stack-Klasse
public class Stack<T>
{
T[] items;
int count;
public void Push(T item) { ... }
public T Pop() { ... }
}
- 7. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Anwendung
Wenn die generische Klasse Stack<T> benutzt werden soll,
dann wird <T> überall durch den gewünschten Typ ersetzt
•Es handelt sich aber nicht einfach um eine Textersetzung
•Die neue Klasse heißt „konstruierter Typ“
•Für jeden anderen Typ wird der Code neu „expandiert“
Beispiel: Mit Stack-Klasse
Stack<int> stack = new Stack<int>();
stack.Push(3);
int i = stack.Pop();
public class Stack
{
int[] items;
int count;
public void Push(int item) { ... }
public int Pop() { ... }
}
public class Stack
{
int[] items;
int count;
public void Push(int item) { ... }
public int Pop() { ... }
}
- 8. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Anwendung
Der konstruierte Typ Stack<int> hat den festen Typ
int
Die Daten werden im konstruierten Typ tatsächlich als
int gespeichert
Typ-Umwandlungen sind deshalb nicht mehr erforderlich
Nachteil:
•Es wird mehr Code (im Speicher) erzeugt, wenn der
generische Typ mehrfach expandiert wird
Stack<string> sts = new Stack<string>();
Stack<double> std = new Stack<double>();
Stack<DateTime> stdt = new Stack<DateTime>();
- 9. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Demo 1
Programmierung einer Stack-Klasse als
generischer Typ
Push- und Pop-Methode implemetieren
Einfache Variante mit festem Array ohne
Prüfung der Indices
Anwendung
IL-Code
- 10. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Demo 2
Programmierung einer generischen Klasse Swap
Austausch zweier einfacher Objekte (double, int, o.ä.)
Benutzung der Swap-Klasse mit unserem generischen
Typen Stack
•Austausch zweier Stacks
•Es wird also ein neuer Swap-Typ konstruiert, der
wiederum konstruierte Stack-Typen korrekt verarbeitet
- 11. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Generische Klassen
Generische Typ-Deklarationen können beliebig
viele Typ-Parameter enthalten
Beispiel:
public class Directory<K,V>
{
public void Add(K key, V value) { ... }
public V this[K key] { ... }
}
//---------------------------------------------
Directory<string,Customer> dict =
new Directory<string,Customer>();
dict.Add(„Bernd“, new Customer());
Customer c = dict[„Peter“];
- 12. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Einschränkungen
Einschränkungen (oder Constraints) definieren für die
Typ-Parameter bestimmte Einschränkungen
(Interfaces, struct, class, new())
Beispiel:
•Für einen Typ-Parameter solle die Methode CompareTo
benutzt werden
•Dann muss der Typ-Parameter diese Methode (über die
Schnittstelle IComparable) implementieren
•Dies wird mit folgender Einschränkung sichergestellt (zur
Übersetzungszeit):
public class Directory<K,V> where K: IComparable
{
}
- 13. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Generische Methoden
In Methodenaufrufen können generische Typen als Parameter
verwendet werden
Man nennt diese Methoden: generische Methoden
Beispiel 1: Funktioniert nur mit Stack<int>
void PushMultiple(Stack<int> stack, params int [] values)
{
foreach(int i in values)
{
stack.Push(i);
}
}
//------------------------------------------------------
Stack <int> stack = new Stack<int>();
PushMultiple(stack, 1, 2, 3, 4);
- 14. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Generische Methoden
Damit PushMultiple mit allen Typen funktioniert,
muss eine generische Methode implementiert werden
Beispiel 2: Funktioniert immer
void PushMultiple<T>(Stack<T> stack, params T [] values)
{
foreach(T val in values)
{
stack.Push(val);
}
}
//------------------------------------------------------
Stack<int> stack = new Stack<int>();
PushMultiple<int>(stack, 1, 2, 3, 4);
- 15. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Generics im Framework
Namensraum:
•System.Collections.Generics
Stack
List
Queue
Dictionary
SortedDictionary
…
Demo04A
•Benutzung der Generics im Framework
- 16. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Warum generische Typen?
Typsicherheit
•Compilerfehler
Code besser lesbar
Performance
•Kein Boxing und Unboxing der Werte!
Demo 4B: Performance-Test
•Standard-Collection
•Generischer Typ
- 17. © 2005 newtelligence Aktiengesellschaft. All rights reserved
C++: Generics und Templates!
Generics:
•Spezialisierung zur Laufzeit
•Die CLR kennt die neuen Typen
•Können von allen .NET-Spachen benutzt
werden
Templates:
•Spezialisierung durch den C++-Compiler
•Die CLR weiß nichts über die Templates
•Können nur mit C++ benutzt werden
VS Beta1: keine Performance-Unterschiede
- 18. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Iteratoren
Bisher waren die Implementierung von Enumeratoren nicht so
einfach (Positionierung!)
Iteratoren ermöglichen jetzt eine ganz einfache Implementierung
der Methode GetEnumerator()
Interface implementieren: IEnumerable
Dadurch kann man mit foreach sehr leicht durch die Collection
iterieren
•Rückgabe der Datenwerte mit yield return
Gibt den Datenwert zurück und unterbricht die Schleife
•Beendigung (wenn nötig) mit yield break;
GetEnumerable() kann „generisch“ implementiert werden
- 19. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Demo 5
Erweiterung des generischen Typs Stack mit
der Methode GetEnumerable()
•Hier: Generische Implementierung für den
jeweiligen Typ des Stacks
Benutzung einer foreach-Schleife, um den
gesamten Stack auszugeben
- 20. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Anonyme Methoden
Event-Handler werden bisher immer über Delegates mit
separaten Methoden aufgerufen
Mit „anonymen Methoden“ kann der Code quasi „inline“
abgelegt werden
Es können Parameter übergeben werden
addButton.Click += delegate
{
...
}
//-----------------------------------------------------
addButton.Click += delegate(object sender, EventArgs e)
{
...
}
- 21. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Demo 6
Windows-Forms-Applikation
Implementierung der alten Variante mit
separater Methode als Event-Handler
Implementierung der gleichen Logik mit einer
anonymen Methode
•Man kann auf die Klassen-Variablen zugreifen
Hinweis: Bei anonymen Methoden werden ggf.
implizite Typ-Umwandlungen durchgeführt
- 22. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Partielle Klassen
Klassen können auf mehrere Dateien verteilt werden
Ist in großen Projekten mit mehreren Entwicklern
sehr angenehm
Der Entwickler kann den Code sinnvoll aufteilen
•Wizard-erzeugter Code
•Von Hand-erzeugter Code
Schlüsselwort partial wird benutzt
Der Compiler fügt im Prinzip alle Dateien einer Klasse
mit dem Schüsselwort partial zusammen
Intellisense funktioniert trotzdem
- 23. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Demo 7
Demonstration der partiellen Klassen
Klasse Test ist auf zwei Dateien verteilt
•Methoden werden „hin und her“ aufgerufen
Hinweis: partial kann auch benutzt werden,
wenn alles nur in einer Datei codiert ist (gibt
keine Fehlermeldung)
- 24. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Sonstige Erweiterungen in C#
Nullable Types
Der ::-Operator
Statische Klassen
get- und set-Zugriff
Co- und Contravariance
Fixed Size Buffers
Friend Assemblies
Compiler-Features
- 25. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Nullable Types
„Nullable“ Typen können einen undefinierten
Zustand haben
Syntax:
•T? oder System.Nullable<T>
Abfrage mit Property: HasValue
Property Value ergibt der Wert oder eine
InvalidOperationException (wenn
null)
- 26. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Nullable Types
Ein „nullable“ Typ kann seinen grundlegenden
Datentyp enthalten und zusätzlich auch den
Wert „null“
Interessant für Datenbankabfragen
// Nullable Typ Beispiel
int? x;
if (x != null) {
Console.WriteLine(x.Value);
}
else {
Console.WriteLine("Undefined");
}
- 27. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Der ::-Operator
Definiert die Suche nach bestimmten Typen
using System;
class MyApp {
public class System { } // Das gibt Probleme: 'System'
const int Console = 7; // Und das auch: 'Console'
const int myInt = 66;
static void Main()
{
Console.WriteLine(myInt); // Error
System.Console.WriteLine(myInt); // Error
global::System.Console.WriteLine(myInt); // OK
}
}
- 28. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Statische Klassen
Statische Klassen ist der sichere Weg, um
Klassen zu definieren, die nicht instanzierbar
sind
•Statische Klassen können nur statische Member
enthalten
•Statische Klassen können nicht instanziert
werden
•Statische Klassen sind versiegelt (sealed)
•Statische Klassen dürfen keinen Konstruktor
enthalten
- 29. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Statische Klassen
Beispiel:
using System;
static class Test
{
public static double Convert(int iWert); // OK
public static string CalcData(...); // OK
public int DoSomething(...); // ERROR!
}
// Zugriff:
double d = Test.Convert(4);
string strOut = Test.CalcData(...);
Test t = new Test(); // ERROR!
- 30. © 2005 newtelligence Aktiengesellschaft. All rights reserved
get- und set-Zugriff
set- und get können unterschiedliche
Zugriffsrechte haben
Beispiel:
public string Name // public!!!
{
get
{
return name;
}
protected set // protected!!!
{
name = value;
}
}
- 31. © 2005 newtelligence Aktiengesellschaft. All rights reserved
get- und set-Zugriff
Geht nicht bei Interfaces
Es müssen beide Methoden (get und set)
implementiert sein
Das Zugriffsverhalten für den Accessor muss
immer restriktiver sein, als beim Property selbst
Wenn override benutzt wird, dann müssen
die Zugriffsoperatoren zueinander passen
- 32. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Co- und Contravariance
Erlaubt bei delegates die Benutzung von
abgeleiteten Klassen als return- bzw.
Parameterwert
•Typ kann die Klasse selbst oder eine davon
abgeleitete Klasse sein
Man benötigt nicht so viele delegates
- 33. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Co- und Contravariance
class Mammals { }
class Dogs : Mammals { }
class Program
{
public delegate Mammals MyHandler();
public static Mammals MyFirstHandler() { return null; }
public static Dogs MySecondHandler() { return null; }
static void Main(string[] args)
{
MyHandler handler_1 = new MyHandler(MyFirstHandler);
// Covariance ermöglicht dieses delegate:
MyHandler handler_2 = new MyHandler(MySecondHandler);
}
}
- 34. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Fixed Size Buffers
Fixed size buffers sind wichtig wenn alter
(unmanaged) Code benutzt werden soll
Beispiel:
...
unsafe // Ist erforderlich für fixed size buffers
{
public struct MyArray
{
public fixed char pathName[128]; // 256 bytes
private int reserved; // 4 bytes
} // Tot.: 260 bytes
}
...
- 35. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Friend Assemblies
Alle NICHT-öffentlichen Typen in einem
Assembly „A“ können von einem Assembly „B“
benutzt werden, wenn „A“ als friend von „B“
deklariert ist
Public Key Token muss bekannt sein
Beispiel:
[assembly:InternalsVisibleTo("AssemblyB",
PublicKeyToken="32ab4ba45e0a69a1")]
- 36. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Compiler-Features
/platform
•/platform:x86
•/platform:Itanium
•/platform:x64 // AMD
•/platform:anycpu // default
#pragma warning
•#pragma warning disable liste
•#pragma warning restore liste
- 37. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Kompatibilität zu C# 1.0
Die Neuerungen in C# 2.0 brechen nicht die
Kompatibilität zur Version 1.0
Alter Code sollte also ohne Änderungen
übernommen werden können
Die Neuerungen der Version 2.0 können nach
und nach benutzt werden, um den existierenden
Code zu vereinfachen
•Man muss aber nicht sofort umstellen (z.B. auf
generische Typen)
- 38. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Zusammenfassung
Endlich gibt es generische Typen
Auch die anderen Erweiterungen sind nützlich
•Viel Vereinfachungen in der Programmierung
Kompatibilität zu C# 1.0 ist gegeben
•Hier und da können Warnungen kommen
•Können aber schnell behoben werden
•C#-Kompatiblität nicht mit Runtime-
Kompatibilität verwechseln!!!
- 39. © 2005 newtelligence Aktiengesellschaft. All rights reserved
Thank You
© 2005 newtelligence® Aktiengesellschaft
newtelligence® AG
Gilleshütte 99
D-41352 Korschenbroich
http://www.newtelligence.com
info@newtelligence.com
The presentation content is provided for your personal information
only. Any commercial or non-commercial use of the presentation in
full or of any text or graphics requires a license from newtelligence
AG.
This presentation is protected by the German Copyright Act, EU
copyright regulations and international treaties.
Notes de l'éditeur
- &lt;number&gt;