C# 4.0 et les améliorations à la BCL
Découvrez le framework .NET 4.0 : • les apports au langage• Quelques améliorations de la « Base Class Library »
Pierre-Emmanuel Dautreppe – 04 Mars 2010
[email protected] – www.pedautreppe.com – @pedautreppe
2
Evolution du langage
C# 1.0
(Nov. 2001)
C# 2.0
(Oct. 2005)
C# 3.5
(3.0: Nov. 2006)
(3.5: Nov. 2007)
(3.5sp1: Nov.2008)
C# 3.5 : LINQ et méthodes lambdas
LINQ Programmation déclarative Concis, mais statiquement typé
Méthodes Lambdas Programmation fonctionnelle
Meta-Programmation Le code devient une donnée Expression Trees
C# 2.0 : Génériques
Apparition des génériques : type safety Correction de manques
Types nullables Classes statiques
Simplifications Méthodes anonymes Itérateurs (yield)
C# 1.0 : Toute la base
Code Managé Common Type System Programmation Orientée Objets Méthodes, Propriétés, Indexeurs, Evènements Compatibilité avec autres technologies
Interopérabilité COM P/Invoke Code Unsafe
3
Tendances d’évolution de .NET
Programmation Déclarative
Progammation Dynamique
Concurrence / Parallélisation
Programmation Déclarative
CommentImpératif Déclaratif
from i in listwhere i > 10orderby iselect i
foreach ( int i in list ) if ( i > 10 ) result.Add(i);result.Sort();
Programmation Dynamique
Ecriture Dynamique
Typage Implicite
Ecriture
Statique
Concurrence / Parallélisation
Architectures multi-cœur Serveurs multi-processeurs Tirer parti de l’amélioration possible des
performances en se reposant sur des frameworks en programmant différement
Simplifier la prise en compte de la parallélisation
4
Agenda
C# 1.0
C# 2.0
C# 3.0
C# 1.0
C# 2.0
C# 3.0
C# 4.0
C# 4.0
Co & Contra Variance des génériques
Paramètres nommés et optionnels
Types dynamiques
Interopérabilité COM
Améliorations à la Base Class Library
Conclusion
5
C# 4.0
Co & Contra Variance des génériques
Paramètres nommés et optionnels
Types dynamiques
Interopérabilité COM
Améliorations à la Base Class Library
Conclusion
6
Co & Contra Variance – Définition
Contravariance Un opérateur de conversion de type est contravariant s’il
ordonne les types du plus générique au plus spécifique
Covariance Un opérateur de conversion de type est covariant s’il
ordonne les types du plus spécifique au plus générique Si tu me fournis une SqlCommand, alors je peux me
contenter de la traiter comme une DbCommand
Si tu sais comparer deux « object », alors tu sauras aussi comparer deux « EventArgs ».
Ainsi, si tu as besoin d’un comparateur d’EventArgs, alors je peux te donner un comparateur d’objet
7
Co & Contra Variance – Les delegates – 1/2
public class Employé { }public class Développeur : Employé { }
class Program{ static Employé CréeEmployé() { return null; } static Développeur CréeDéveloppeur() { return null; }
static void Main(string[] args) { var créeEmployé = new Func<Employé>(CréeEmployé); Employé employé1 = créeEmployé(); var créeDeveloppeur = new Func<Employé>(CréeDéveloppeur); Employé employé2 = créeDeveloppeur(); }}
public class Employé { }public class Développeur : Employé { }
class Program{ static Employé CréeEmployé() { return null; } static Développeur CréeDéveloppeur() { return null; }}
Func<Développeur>
Func<Employé>
Les delegates sont covariants
8
Co & Contra Variance – Les delegates – 2/2
void MonHandler(object sender, EventArgs e) { }
TextBox txtBox = new TextBox();txtBox.Click += MonHandler;txtBox.KeyDown += MonHandler;
TextBox txtBox = new TextBox();txtBox.Click +=txtBox.KeyDown +=
Les delegates sont
contravariants
delegate void EventHandler(object sender, EventArgs e);
delegate void KeyEventHandler(object sender, KeyEventArgs e);
9
Covariance des tableaux
string[] strArray = new[] { "A", "B" };object[] objArray = strArray;objArray[0] = 12;string s = strArray[0];
Les arrays sont covariants…
System.ArrayTypeMismatchException
…mais pas “type safe”
Possible seulement pour les types références
Il s’agit ici d’une conversion par “boxing” Interdit
int[] intArray = new[] { 1, 2, 3};object[] objArray = intArray;
10
Co & Contra Variance des types génériques – 1/4
Génériques = Sécurité de typage
List<string> strArray = new List<string> { "A", "B" };List<object> objArray = strArray;
List<string> strArray = new List<string> { "A", "B" };IEnumerable<object> objEnum = strArray;
Non « Type Safe » donc non covariant
« Type Safe » donc covariant
11
Co & Contra Variance des types génériques – 2/4
IComparer<string> stringComparer = new MyStringComparer();IComparer<object> objectComparer = new MyObjectComparer();TestContravariance(stringComparer);TestContravariance(objectComparer);
public class MyObjectComparer : IComparer<object> { ... }public class MyStringComparer : IComparer<string> { ... }
public void TestContravariance(IComparer<string> comparer){ comparer.Compare("chaine 1", "chaine 2");}
IComparer<T> est contravariant
IComparer<string> stringComparer = new MyStringComparer();stringComparer.Compare("chaine 1", "chaine 2");
IComparer<object> objectComparer = new MyObjectComparer();objectComparer.Compare("chaine 1", "chaine 2")
12
Co & Contra Variance des types génériques – 3/4
public interface IEnumerable<out T> : IEnumerable{ IEnumerator<T> GetEnumerator();}
Mot-clé « out » T ne doit être utilisé que comme type de retour IEnumerable<T> est covariant
IEnumerable<B> est considéré comme IEnumerable<A> si conversion de référence de B vers A
A B
IEnumerable<A> IEnumerable<B>
13
Co & Contra Variance des types génériques – 4/4
Mot-clé « in » T ne doit être utilisé que comme paramètre d’input IComparer<T> est contravariant
IComparer<A> est considéré comme IComparer<B> si conversion de référence de B vers A
public interface IComparer<in T>{ int Compare(T x, T y);}
A B
IComparer<A> IComparer<B>
14
Variance en .NET 4.0
System.Collections.Generic.IEnumerable<out T>System.Collections.Generic.IEnumerator<out T>System.Linq.IQueryable<out T>System.Collections.Generic.IComparer<in T>System.Collections.Generic.IEqualityComparer<in T>System.IComparable<in T>
System.Func<in T, …, out R>System.Action<in T, …>System.Predicate<in T>System.Comparison<in T>System.EventHandler<in T>
Interfaces
Delegates
15
C# 4.0
Co & Contra Variance des génériques
Paramètres nommés et optionnels
Types dynamiques
Interopérabilité COM
Améliorations à la Base Class Library
Conclusion
16
Paramètres Optionnels et Nommés – 1/4
FileStream Open(string path, FileMode mode, FileAccess
access, FileShare share)
FileStream Open(string path, FileMode mode, FileAccess
access)FileStream Open(string path,
FileMode mode)
Une méthode principale
Plusieurs overloads
Redirection avec des valeurs par
défaut
17
Paramètres Optionnels et Nommés – 2/4
Methode(10); //Equivalent à Methode(10, 5, 10);
Methode(10, , 15); //INTERDIT
Methode(10, 2, 15);
Methode(10, 2); //Equivalent à Methode(10, 2, 10);
public void Methode(int x, int y = 5, int z = 10) { }
2 paramètres optionnels
Les paramètres omis doivent être en
dernier
18
Paramètres Optionnels et Nommés – 3/4
Methode(10, z: 15);
Methode(y: 15, x: 10);Methode(y: 15, x: 10, z: 2);
Les paramètres nommées doivent être en dernier
Les paramètres non optionnels doivent être
spécifiés
Les paramètres nommés peuvent être dans
n’importe quel ordre
Les paramètres nommés sont évalués dans l’ordre d’écriture
19
Paramètres Optionnels et Nommés – 4/4
Identique à VB.NET
Paramètres optionnels Doivent être des constantes de compilation Valeur par défaut copiée dans l’appel
Paramètres nommés La compilation se base sur les noms
Ne changez pas votre API
A utiliser plutôt en temps que client
Même question que pour const ou
static readonly
20
C# 4.0
Co & Contra Variance des génériques
Paramètres nommés et optionnels
Types dynamiques
Interopérabilité COM
Améliorations à la Base Class Library
Conclusion
21
Exemples appels « dynamiques » avec C# 3.5
object calculator = GetCalculator();Type calcType = calculator.GetType();int result = (int)calcType.InvokeMember("Add", BindingFlags.InvokeMethod, null, calculator, new object[] { 10, 20 });
ScriptScope python = Python.CreateRuntime().UseFile("Calculator.py");ScriptEngine engine = python.Engine;int resultat = (int)engine.Execute ("GetCalculator().Add(10, 20)", python);
ScriptObject calc = GetCalculator();int resultat = (int)calc.Invoke("Add", 10, 20);
Calculator calc = GetCalculator();int resultat = calc.Add(10, 20);
C# C#
C# IronPython
Silverlight Javascript
22
POCOBinder
JavaScript
BinderPythonBinder
RubyBinder
COMBinder
IronPython IronRuby C#Visual Basic
Autres…
Dynamic Language Runtime (DLR)
Expression Trees Dynamic Dispatch Call Site Caching
<
23
Types dynamiques – 1/3
dynamic calc = GetCalculator();int resultat = calc.Add(10, 20);
Calculator calc = GetCalculator();int resultat = calc.Add(10, 20);
Statiquement typé
comme “dynamic”
Appel dynamique de la méthode
Conversion dynamique
de la valeur de retour
24
Types dynamiques – 2/3
Quand les opérandes sont dynamic… La sélection des membres est différée à l’exécution A l’exécution, dynamic est remplacé par le type réel de
chaque membre Le type de retour de l’opération est également dynamic
dynamic x = 1;dynamic y = "Bonjour";dynamic z = new List<int> { 1, 2, 3 };
Type statique (à la compilation) Type dynamique(à l’exécution)
dynamic Int32dynamic Stringdynamic List<int>
25
Types dynamiques – 3/3
public class Calculator{ public double Add(double a, double b) { ... } public int Add(int a, int b) { ... }}
Calculator calc = GetCalculator();double x = 2.25, y = 3.75;double result = calc.Add(x, y);Calculator calc = GetCalculator();dynamic x = 2.25, y = 3.75;dynamic result = calc.Add(x, y);Calculator calc = GetCalculator();dynamic x = 2, y = 3;dynamic result = calc.Add(x, y);
A la compilation : double Add(double, double)
A l’exécution : double Add(double, double)
A l’exécution : int Add(int, int)
26
Types dynamiques – Points à retenir
La résolution des méthodes est différée à l’exécution si nécessaire
public void Methode(dynamic d)
On ne peut pas appeler des méthodes d’extensions
A savoir (ou non): Nouveaux types de conversion : assignation,
structurelle, …
dynamic n’existe pas au niveau du code IL
27
Types dynamiques – Exemples d’écritures – 1/2
Ces écritures sont valides
dynamic MaMethode(int i, dynamic d) { ... }dynamic MaMethode(int i, dynamic d) { ... }
dynamic[] monArray = ...
dynamic MaMethode(int i, dynamic d) { ... }
dynamic[] monArray = ...
IEnumerable<dynamic> enumerable = ...
dynamic MaMethode(int i, dynamic d) { ... }
dynamic[] monArray = ...
IEnumerable<dynamic> enumerable = ...
List<dynamic> liste = ...
dynamic MaMethode(int i, dynamic d) { ... }
dynamic[] monArray = ...
IEnumerable<dynamic> enumerable = ...
List<dynamic> liste = ...
class BaseClass<T> { }class Derived : BaseClass<dynamic> { }
28
Types dynamiques – Exemples d’écritures – 2/2
Ces écritures ne sont pas valides
class C : dynamic { }class C : dynamic { }
class C : IEnumerable<dynamic> { }
class C : dynamic { }
class C : IEnumerable<dynamic> { }
class C<T> where T : BaseClass<dynamic> { }
Pour plus d’information : Blog de Chris Burrows http://blogs.msdn.com/cburrows/default.aspx
29
Créer un type dynamique – 1/2
public class DynamicObject : IDynamicMetaObjectProvider{ public virtual IEnumerable<string> GetDynamicMemberNames(); public virtual DynamicMetaObject GetMetaObject(Expression
parameter); public virtual bool TryConvert(ConvertBinder binder, out object
result); public virtual bool TryDeleteMember(DeleteMemberBinder binder); public virtual bool TryGetMember(GetMemberBinder binder,
out object result); public virtual bool TrySetMember(SetMemberBinder binder, object
value); public virtual bool TryBinaryOperation(BinaryOperationBinder
binder, object arg, out object
result); public virtual bool TryUnaryOperation(UnaryOperationBinder binder,
out object result); ...}
Dans System.Core.dllNamespace
System.Dynamic
IDynamicObject a été renommé
30
Créer un type dynamique – 2/2
public class MonDynamicObject : DynamicObject{ Dictionary<string, object> dic = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{ return this.dic.TryGetValue(binder.Name, out result); }
public override bool TrySetMember(SetMemberBinder binder, object value)
{ this.dic[binder.Name] = value; return true; }}
dynamic monObjet = new MonDynamicObject();monObjet.Nom = "Dautreppe";monObjet.Prenom = "Pierre-Emmanuel";Console.WriteLine(monObjet.Prenom + " " +
monObjet.Nom);
31
Types dynamiques – Utilisation de la classe Expandostatic void Main() { dynamic personne = new ExpandoObject(); //1. Définir des propriétés personne.Nom = "Dautreppe"; personne.Prenom = "Pierre-Emmanuel";
//2. Définir des méthodes personne.ToString = new Func<string>( () => personne.Nom + " " +
personne.Prenom ); Console.WriteLine(personne.ToString());
//3. Définir un évènement personne.MonEvent = null; personne.OnMonEvent = new Action<EventArgs>((e) => {
if (personne.MonEvent != null) personne.MonEvent(personne, e); });
personne.MonEvent += new EventHandler(MonEventHandler); personne.OnMonEvent(EventArgs.Empty);}
private static void MonEventHandler(dynamic obj, EventArgs e) { Console.WriteLine("MonEvent appelé sur '" + obj.ToString());}
32
Types dynamiques – Conclusion – 1/2
Que peut-on appeler ? Toute méthode définie sur l’instance
Méthode publique Méthode protected Méthode private (de l’instance) Méthode d’interface (si implémentation implicite)
Que ne peut-on pas appeler ? Toute méthode « n’existant pas » sur l’instance
Méthode private (d’une classe de base) Méthode static (quelque soit sa visibilité) Méthode d’interface (si implémentation explicite) Méthode d’extension
33
Types dynamiques – Conclusion – 2/2
Quand doit-on les utiliser ? Quand on travaille sans type (par ex. réflexion) Quand on fait de l’interop
COM Silverlight Javascript …
Compenser des manques du Framework « INumeric »
Quand ne devrait-on pas les utiliser ? Pour compenser une erreur de design
Eg Coder en utilisant une classe de base, mais avoir besoin d’une connaissance des types dérivés
34
C# 4.0
Co & Contra Variance des génériques
Paramètres nommés et optionnels
Types dynamiques
Interopérabilité COM
Améliorations à la Base Class Library
Conclusion
35
Interopérabilité COM – 1/3
doc.SaveAs("Test.docx");
Paramètres optionnels et nommés
object fileName = "Test.docx";object missing = System.Reflection.Missing.Value;
doc.SaveAs(ref fileName, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing);
Les APIs COM déclarent des paramètres optionnels « ref » n’est plus obligatoire
36
Interopérabilité COM – 2/3
COM et dynamic
IExcel.Trendlines trendLines =
(IExcel.Trendlines)serie.Trendlines(Type.Missing);
IExcel.Range cell = (IExcel.Range)sheet.Cells[row, column];
IExcel.Trendlines trendLines = serie.Trendlines();
IExcel.Range cell = sheet.Cells[row, column];
Les APIs COM renvoient des dynamic Conversion d’assignation vers le type désiré
37
Interopérabilité COM – 3/3
« No PIA » : Pas de « Primary Interop Assemblies »
namespace OfficeApplication{ class Program { static void Main(string[] args) { Application excel = new Application(); Worksheet sheet = excel.Sheets.Add(); ChartObjects charts = sheet.ChartObjects(); ChartObject chart = charts.Add(10, 10, 100, 100); SeriesCollection series = chart.Chart.SeriesCollection(); Series serie = series.Add(...); Trendlines trendLines = serie.Trendlines(); Range cell = sheet.Cells[10, 10]; } }}
Par défaut : True
38
C# 4.0
Co & Contra Variance des génériques
Paramètres nommés et optionnels
Types dynamiques
Interopérabilité COM
Améliorations à la Base Class Library
Conclusion TUples
System.IO
Fichiers mappés
Code Contracts
Parallel Extensions
System.Numerics
39
BCL – Tuples – 1/2
public Tuple<bool, int> TryGetElement(string key){ int valeur; bool result = dic.TryGetValue(key, out valeur); return new Tuple<bool, int>(result, valeur);}
public static class Tuple{ public static Tuple<T1> Create<T1>(T1 item1); public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2);
... ...
public static Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> Create<T1, T2, T3, T4, T5, T6, T7, Trest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest);
}
Supporté nativement par F# et
IronPython
System.Tuple :Factory de Tuple<...>
De 1 à 8 types génériques
Typiquement un autre Tuple<...>
return Tuple.Create(result, valeur);
40
BCL – Tuples – 2/2
« new Tuple » et « Tuple.Create » sont équivalents
var a = new Tuple<int, int, int, int, int, int, int, Tuple<int, int>> (1, 2, 3, 4, 5, 6, 7, new Tuple<int, int>(8, 9));var b = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9));
var a = new Tuple<int, int, int, int, int, int, int, Tuple<int, int>> (1, 2, 3, 4, 5, 6, 7, new Tuple<int, int>(8, 9));var b = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9));
Console.WriteLine(a.Item5); // 5Console.WriteLine(a.Rest.Item2); // 9
var a = new Tuple<int, int, int, int, int, int, int, Tuple<int, int>> (1, 2, 3, 4, 5, 6, 7, new Tuple<int, int>(8, 9));var b = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9));
Console.WriteLine(a.Item5); // 5Console.WriteLine(a.Rest.Item2); // 9
Console.WriteLine(b.Item5); // 5Console.WriteLine(b.Rest.Item1.Item2); // 9
presque !!
Rest = Tuple<int, int>
Rest = Tuple<Tuple<int, int>>
41
BCL – Améliorations à System.IO
var errorlines =from file in Directory.EnumerateFiles(@"C:\logs", "*.log")from line in File.ReadLines(file)where line.StartsWith("Error:")select string.Format("File={0}, Line={1}", file, line);
File.WriteAllLines(@"C:\errorlines.log", errorlines);
var errorlines =from file in Directory.GetFiles(@"C:\logs", "*.log")from line in File.ReadAllLines(file)where line.StartsWith("Error:")select string.Format("File={0}, Line={1}", file, line);
File.WriteAllLines(@"C:\errorlines.log", errorlines);
IEnumerable<string> EnumerateFiles(string path, string
searchPattern);
void WriteAllLines(string path, string[] contents);
string[] ReadAllLines(string path);
string[] GetFiles(string path, string searchPattern);
void WriteAllLines(string path, IEnumerable<string> contents);
IEnumerable<string> ReadLines(string path);
42
BCL – Fichiers mappés en mémoire – 1/2
Gros FichierProcess 1
Environment.SystemPageSize
Vue N
Vue 2
Vue 1
Exploite la mémoire paginée du système
Taille de la vue <= Mémoire disponible pour mapping
(2Gb sur 32 bits)
Stream (lecture séquentielle)Accessor (lecture aléatoire)
Ressource partagée
Process 1 Process 2
Vue N Vue N Vue 1Vue 1
Scénario 1
Scénario 2
Gestion de la mémoire par le système
Pagination automatique en mémoire
Mémoire partagée Simplification pour IPC (Inter-Process Communication)
43
BCL – Fichiers mappés en mémoire – 2/2
using (var mmf = MemoryMappedFile.CreateNew("FichierMappé", 1000)){ using (var stream = mmf.CreateViewStream()) new BinaryWriter(stream).Write("Bonjour");
var startInfo = new ProcessStartInfo("AutreProcess.exe"); startInfo.UseShellExecute = false; Process.Start(startInfo).WaitForExit();}
using (var mmf = MemoryMappedFile.OpenExisting("FichierMappé")){ using (var stream = mmf.CreateViewStream()) Console.WriteLine(new BinaryReader(stream).ReadString());}
Process 1
Process 2
Ou mmf.CreateViewAccessor
44
CodeContracts – 1/2
Permettre l’ajout de contrats dans le code Disponible dans 3.5 (installation séparée)
4 parties Une nouvelle API System.Diagnostics.Contracts Le « rewriter » (ccrewrite.exe)
Injecte le code de vérification des contrats « aux bons endroits »
Le « static checker » (cccheck.exe) Analyse le code pour vérifier si les contrats sont respectés
Le générateur d’assembly (ccrefgen.exe) Produit une DLL avec les contrats seuls
45
CodeContracts – 2/2
public class CompteBancaire{ private int numeroCompte, modulo; private double solde;
public void EffectueDepot(double montant) { this.solde += montant; }
static void Main() { var compte = new CompteBancaire { numeroCompte = 0011234567, modulo = 27 }; compte.EffectueDepot(1000); }}
public class CompteBancaire{ private int numeroCompte, modulo; private double solde;
public void EffectueDepot(double montant) { Contract.Requires(montant > 0); this.solde += montant; }
static void Main() { var compte = new CompteBancaire { numeroCompte = 0011234567, modulo = 27 }; compte.EffectueDepot(1000); }}
public class CompteBancaire{ private int numeroCompte, modulo; private double solde;
public void EffectueDepot(double montant) { Contract.Requires(montant > 0); Contract.Ensures(ancien solde < nouveau solde); this.solde += montant; }
static void Main() { var compte = new CompteBancaire { numeroCompte = 0011234567, modulo = 27 }; compte.EffectueDepot(1000); }}
public class CompteBancaire{ private int numeroCompte, modulo; private double solde;
public void EffectueDepot(double montant) { Contract.Requires(montant > 0); Contract.Ensures(Contract.OldValue(this.solde) < this.solde); this.solde += montant; }
static void Main() { var compte = new CompteBancaire { numeroCompte = 0011234567, modulo = 27 }; compte.EffectueDepot(1000); }}
public class CompteBancaire{ private int numeroCompte, modulo; private double solde;
public void EffectueDepot(double montant) { Contract.Requires(montant > 0); Contract.Ensures(Contract.OldValue(this.solde) < this.solde); this.solde += montant; }
[ContractInvariantMethod] private void ObjectInvariant() { Contract.Invariant(this.solde >= 0); Contract.Invariant(this.numeroCompte % 97 == this.modulo); }
static void Main() { var compte = new CompteBancaire { numeroCompte = 0011234567, modulo = 27 }; compte.EffectueDepot(1000); }}
• Contract.Requires• Pré-condition• Evalué « avant » l’appel
• Contract.Ensures• Post-condition• Evalué « après » l’appel
• Contract.OldValue• Retourne la valeur avant
l’appel
• ContractInvariantMethod• Invariance de l’objet• Appelé après chaque
appel public
46
PFX – Parallel Framework Extensions
static void Main(){ IEnumerable<int> liste = Enumerable.Range(0, 10000000); var query = from i in liste where EstNombrePremier(i) select i; Console.WriteLine(query.Count());}
static bool EstNombrePremier(int p){ int limite = (int)Math.Sqrt(p); for (int i = 2; i <= limite; i++) if (p % i == 0) return false; return true;}
Parallel.Invoke(() => RealiseAction1(), () => RealiseAction2(), () => RealiseAction3());
• System.Collection.Concurrent• BlockingCollection<T>• ConcurrentQueue<T>• ConcurrentDictionary<K, V>
• Lazy<T>
• System.Threading• SemaphoreSlim• ManuelResetEventSlim• SpinLock
• Visual Studio• Nouveau Debugger• Nouveau Profiler
.AsParallel()
47
System.Numerics – 1/2
Une nouvelle DLL : System.Numerics.dll BigInteger
Un entier, « arbitrairement grand » Complex
Structure pour représenter des nombres complexes
48
System.Numerics – 2/2
BigInteger
static BigInteger Factorielle(BigInteger i){ if (i == 2) return 2; return i * Factorielle(--i);}
static void Main(){ Console.WriteLine(Factorielle(5));}
120
static BigInteger Factorielle(BigInteger i){ if (i == 2) return 2; return i * Factorielle(--i);}
static void Main(){ Console.WriteLine(Factorielle(5)); Console.WriteLine(Factorielle(10));}
1203628800
static BigInteger Factorielle(BigInteger i){ if (i == 2) return 2; return i * Factorielle(--i);}
static void Main(){ Console.WriteLine(Factorielle(5)); Console.WriteLine(Factorielle(10)); Console.WriteLine(Factorielle(55));}
120362880012696403353658275925965100847566516959580321051449436762275840000000000000
static BigInteger Factorielle(BigInteger i){ if (i == 2) return 2; return i * Factorielle(--i);}
static void Main(){ Console.WriteLine(Factorielle(5)); Console.WriteLine(Factorielle(10)); Console.WriteLine(Factorielle(55)); Console.WriteLine(Factorielle(542));} 120
3628800126964033536582759259651008475665169595803210514494367622758400000000000001607535095378011891056328484225529595243838798499054994766025156939288169810835272449306354580237969682411561904659247352233869578500369085015849202525200// 11 autres lignes de chiffres27593805066916468242618448796850243328574235699250768859321062302677755711983880776617227228201878615112377392168960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
• Prévu pour .NET 3.5• Retardé pour problème de
performance
• Toutes opérations de int
• Autres opérations (statiques)• Abs• DivRem• GreatestCommonDivisor• Remainder
49
C# 4.0
Co & Contra Variance des génériques
Paramètres nommés et optionnels
Types dynamiques
Interopérabilité COM
Améliorations à la Base Class Library
Conclusion
50
Conclusion – 1/2
& Framework 4.0
Nouveautés au niveau du langage Codage
Simplifications d’écriture Amélioration des performances
Design Interopérabilité simplifiée et homogénéisée « Design By Contracts » Framework de concurrence
51
Conclusion – 2/2
Nouveautés au niveau de l’environnement Team Foundation Server se démocratise Nouveaux debuggers Modélisation UML
Nouveautés au niveau des frameworks ASP.NET, MVC, AJAX 4.0, Sync Framework, F#…
Et Après ? C# 5.0 (?) : « Compiler As A Service »
Tout simplement une nouvelle révolution
52
N’oubliez pas votre formulaire de
participation au concours!
Prochains évènements 09/03 : Windows Live Meeting – VS 2010 - .NET 4.0 23/03 : MyTIC : Sharepoint 2010 30/03 au 01/04 : Tech Days 2010 21/04 : DotNetHub : Méthodes Agiles 28/04 : DotNetHub : NService Bus
Merci à tous !