Découvrez C# 4.0 et les améliorations apportées à la BCL

Post on 07-Nov-2014

2.116 views 1 download

description

 

Transcript of Découvrez C# 4.0 et les améliorations apportées à la BCL

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

pierre@dotnethub.be – 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 !