C# et .NET
                       Enigmes et Puzzles
                        Clément Gatin, Luc Vo Van
                                      Consultants Dev
                                            Microsoft




Code / Développement
Donnez votre avis !
                   Depuis votre smartphone, sur :
                    http://notes.mstechdays.fr

    De nombreux lots à gagner toutes les heures !!!
               Claviers, souris et jeux Microsoft…

       Merci de nous aider à améliorer les TechDays

http://notes.mstechdays.fr
Présentation de Microsoft Enterprise Services

                                                      Application Critiques (Tier1)

                                                      Relation client et ressources (ERP / CRM)

                                                      Collaboration & social
 Entreprise   Microsoft
                                    Support Premier
 Strategy     Consulting Services                     Productivité dans le Cloud

                                                      Productivité On Premise

                                                      Environnement de travail

                                                      Datacenter et Cloud
4 ouvrages écrits par 13 Microsoftees




http://www.editions-eyrolles.com/livres/Windows-8-pour-les-professionnels
Agenda
Introduction et objectifs

Les énigmes
   1.   Typage explicite (ou pas)
   2.   Plus Plus
   3.   Remise à Zéro
   4.   (D)étonnante combinaison
   5.   C# dans tous ses états
   6.   Bouquet final
INTRODUCTION ET OBJECTIFS
Pourquoi cette session ?
Approfondir la connaissance d’un outil fondamental

Apprécier la sophistication du compilateur

Repartir avec quelques bonnes pratiques

Se tester !
Visual C#
Historique en bref


Spécifications du langage
Enigme 0 : Où trouver la spécification ?
A.   Sur Internet
B.   Sur le blog d’Anders Hejlsberg
C.   Je l’ai toujours sur moi
D.   Dans l’aide F1 de Visual Studio
Enigme 0 : Où trouver la spécification ?
A.   Sur Internet
B.   Sur le blog d’Anders Hejlsberg
C.   Je l’ai toujours sur moi
D.   Dans l’aide F1 de Visual Studio



C:Program Files (x86)Microsoft Visual Studio 11.0VC#Specifications
Visual C#
Historique en bref


Spécifications du langage


ILDASM
Merci d’être venus si nombreux !
this.Warrior = true;
C’est parti.
Enigme 1

TYPAGE EXPLICITE (OU PAS)
{ typage explicite }
        (ou pas)
Enigme 1 : Quel mot clé est recommandé
?
A. Typage explicite
B. var
C. Aucun
Enigme 1 : Quel mot clé est recommandé
?
A. Typage explicite
B. var
C. Aucun
En synthèse
ILDASM (Intermediate Language Disassembler) est livré avec Visual Studio et
permet de parcourir l’IL

var ou déclaration explicite : c’est pareil

var != dynamic. Réservez dynamic à l’interop !
Enigme 2

PLUS PLUS
{ i++ }
Enigme 2 : Qu’affiche le programme ?
A. 1
B. 2
C. Ne compile pas
Enigme 2 : Qu’affiche le programme ?
A. 1
B. 2
C. Ne compile pas
En synthèse
C# spécifie les comportements de manière détaillée

C’est la fin de l’échauffement !
(petit) rappel

CLASSES ET STRUCTURES
La pile (stack)
La pile (stack)




                  static void Main()
                  {
                      FaitQqch();
                      FaitAutreChose();
                  }
La pile (stack)




                  static void Main()
                  {
                      FaitQqch();
                      FaitAutreChose();
                  }
       Main
La pile (stack)




                  static void Main()
                  {
                      FaitQqch();
                      FaitAutreChose();
       FaitQqch   }
         Main
La pile (stack)




                       static void Main()
                       {
                           FaitQqch();
                           FaitAutreChose();
      FaitAutreChose
                       }
         Main
La pile (stack)




                  static void Main()
                  {
                      FaitQqch();
                      FaitAutreChose();
                  }
       Main
Le tas (heap)
Le tas (heap)



      User utilisateur = new User();
Le tas (heap)



      User utilisateur = new User();
      utilisateur.Name = "Luc";
                                       Luc
Le tas (heap)



     DateTime lucBirth = new DateTime(1979, 11, 28);


                                               Luc
      28/11
      /1978
Le tas (heap)



     DateTime lucBirth = new DateTime(1979, 11, 28);
     utilisateur.BirthDate = lucBirth;

                                             28/11
                                             /1978
                                                     Luc
      28/11
      /1978
Le tas (heap)



     DateTime lucBirth = new DateTime(1979, 11, 28);
     utilisateur.BirthDate = lucBirth;

                                             28/11
                                             /1978
                                                     Luc
      28/11
      /1978
Enigme 3

REMISE À ZÉRO
{ Remise à Zéro }
Enigme 3 : Est-ce que ça compile ?
A.   Oui
B.   Non
C.   Ca dépend des options du compilateur
D.   Ca veut dire quoi « ça compile » ?
Enigme 3 : Est-ce que ça compile ?
A.   Oui
B.   Non
C.   Ca dépend des options du compilateur
D.   Ca veut dire quoi « ça compile » ?
En synthèse
Le compilateur sait (assez) bien déterminer si les chemins
de construction initialisent tous les membres

C’est un mécanisme fondamental du déterminisme de .NET

:this() permet d’enchaîner les ctor pour les objets
complexes

this = new peut impressionner en soirée
                                                             - 40
(petit) rappel

DANS LES COULISSES DES
PROPRIÉTÉS
{ Propriétés }
Enigme 4

(D)ÉTONNANTE COMBINAISON
{ (D)étonnante Combinaison }
Enigme 4 : Qu’affiche le programme ?
A.   False, False
B.   False, True
C.   False, NullReferenceException
D.   La réponse D
Enigme 4 : Qu’affiche le programme ?
A.   False, False
B.   False, True
C.   False, NullReferenceException
D.   La réponse D
En synthèse
Performance sur les objets valeurs
       Pas de garbage collection
       Pas d’indirection de pointeur

Les objets valeurs sont manipulés par copie, donc
       Attention aux mises à jour
       Les copies sont consommatrices en performance et en
       mémoire. 10 appels imbriqués = 10 copies = 10x en RAM

La copie de valeur peut engendrer des bugs difficiles à
diagnostiquer
                                                               - 47
Préconisations
Utilisez les structs pour des objets de petite taille

Evitez les confusions en n’ayant que des structs dont les
champs sont en lecture seule




                                                            - 48
Enigme 5

C# DANS TOUS SES ÉTATS
{ C# dans tous ses états }
          yield return
Enigme 5 : Qu’affiche ce programme
A.   Nom1, Nom2, Clement, Luc
B.   Nom1, Clement, Nom2, Luc
C.   Clement, Luc
D.   Nom1, Nom2
Enigme 5 : Qu’affiche ce programme
A.   Nom1, Nom2, Clement, Luc
B.   Nom1, Clement, Nom2, Luc
C.   Clement, Luc
D.   Nom1, Nom2
Une machine à états ?

                                                            4
                          2



               1                         3                  5




   Une machine à états est un ensemble d’états   n   et de transitions


                                                                         - 53
Une machine à états ?
               public static IEnumerable<string> GetNames()
               {
          1

                   Console.WriteLine("Nom 1");
                   yield return "Clement";
          2

                   Console.WriteLine("Nom 2");
                   yield return "Luc";
           3

               }




                                                              - 54
yield return
Chaque yield return correspond à un état
Le code entre deux yield return correspond à une
transition

Le compilateur créé une classe machine à états
      MoveNext passe à l’état suivant
      L’état en cours est sauvegardé
      Les variables locales de la fonctions sont des
membres
      Chaque appel de MoveNext fait un Goto            - 55
{ C# dans tous ses états }
          async await
async await
Chaque appel à une méthode préfixée de await est un état

Le code entre deux appels est une transition

Lors d’un appel à une méthode async, si après l’appel celle
si n’est pas terminée (IsCompleted = false), un « awaiter »
est créé, qui rappellera la machine à état à la fin de la tâche,
pour continuer à l’état courant


                                                                   - 57
En synthèse
Le compilateur génère des machines à état, qui permettent
d’implémenter les scénarios de « reprise »

yield return et async sont des constructions bien plus
sophistiquées qu’elles n’en ont l’air

L’intelligence et la quantité de code fournie par le
compilateur est appréciable… et permet d’être plus productif


                                                               - 58
Enigme 6

BOUQUET FINAL
{ Bouquet final }
Enigme 6 : Qu’affiche ce programme
A. Alice a 10 ans, Bob a 11 ans, Charlie a 12 ans, Dave a
   13 ans
B. Alice a 10 ans, Alice a 10 ans, Alice a 10 ans, Alice a 10
   ans
C. Dave a 13 ans, Dave a 13 ans, Dave a 13 ans, Dave a
   13 ans
D. Ne compile pas
Enigme 6 : Qu’affiche ce programme
A. Alice a 10 ans, Bob a 11 ans, Charlie a 12 ans, Dave a 13 ans
B. Alice a 10 ans, Alice a 10 ans, Alice a 10 ans, Alice a 10
   ans
C. Dave a 13 ans, Dave a 13 ans, Dave a 13 ans, Dave a 13
   ans
D. Ne compile pas
{ Bouquet final }
     « The Encore »
Enigme 6 : Qu’affiche ce programme
A. Alice a 10 ans, Bob a 11 ans, Charlie a 12 ans, Dave a 13 ans
B. Alice a 10 ans, Alice a 10 ans, Alice a 10 ans, Alice a 10
   ans
C. Dave a 13 ans, Dave a 13 ans, Dave a 13 ans, Dave a 13 ans
D. Ne compile pas
class Main_Scope2
                                             class Main_Scope1                {
                                             {                                    string name;
Visual Studio 2012                               string messageFormat;            Main_Scope1 parentScope;
                                                 List<Action> actions;        }
                                             }
static string[] _Names = new[]
{ "Alice", "Bob", "Charlie" };

static void Main(string[] args)
{
    string messageFormat = "Hello {0}";                           messageFormat = "Hello {0}"
    List<Action> actions = new List<Action>();
                                                                  actions = { }

    for (int i = 0; i < _Names.Length; ++i)
    {
        string name = _Names[i];
        actions.Add(() =>
            Console.WriteLine(messageFormat, name));
    }
                                                            parentScope    parentScope     parentScope
    foreach (var action in actions)                         Name =         Name =          Name =
        action();                                           "Alice"        "Bob"           "Charlie"
    Console.ReadLine();
}

                                                               Action         Action            Action
class Main_Scope1                class Main_Scope2
                                             {                                {
                                                 string messageFormat;
Visual Studio ≤ 2010                             List<Action> actions;        }
                                                                                  Main_Scope1 parentScope;
                                                 string name;
                                             }
static string[] _Names = new[]
{ "Alice", "Bob", "Charlie" };

static void Main(string[] args)
{                                                                 messageFormat = "Hello {0}"
    string messageFormat = "Hello {0}";
                                                                  actions = { }
    List<Action> actions = new List<Action>();                    name ="Charlie"

    string name;
    for (int i = 0; i < _Names.Length; ++i)
    {
        name = _Names[i];
        actions.Add(() =>
           Console.WriteLine(messageFormat, name));
    }
                                                            parentScope    parentScope     parentScope
    foreach (var action in actions)
        action();
    Console.ReadLine();
}
                                                               Action         Action            Action
En synthèse
Les closures sont un outil pratique et élégant dont la
mécanique est implémentée par le compilateur

Les breaking changes au niveau compilation sont
extrêmement rares, et sont pris très au sérieux par Microsoft




                                                                - 67
Conclusion
En synthèse
Les évolutions du langage C# sont principalement liées au
compilateur lui-même, avec peu de support spécifique de la
CLR

Parti d’une programmation purement itérative proche du
langage machine, le C# permet aujourd’hui d’exprimer
élégamment des principes complexes par la génération de
code
        Asynchronisme
        Closures
        Générateurs
                                                             - 69
Pour finir          http://notes.mstechdays.fr

int i = 0;
Console.Write(string.Format("{0} {1} {2} {3}",
                ++i,
                i++ * ++i,
                i,
                i++ + i++));
Donnez votre avis !
                   Depuis votre smartphone, sur :
                    http://notes.mstechdays.fr

    De nombreux lots à gagner toutes les heures !!!
               Claviers, souris et jeux Microsoft…

       Merci de nous aider à améliorer les TechDays

http://notes.mstechdays.fr
Développeurs                                                         Pros de l’IT
 http://aka.ms/generation-app       Formez-vous en ligne        www.microsoftvirtualacademy.com

    http://aka.ms/evenements-
                 developpeurs     Retrouvez nos évènements      http://aka.ms/itcamps-france


            Les accélérateurs
                                  Faites-vous accompagner
Windows Azure, Windows Phone,
                                  gratuitement
                   Windows 8


                                   Essayer gratuitement nos     http://aka.ms/telechargements
                                                 solutions IT

         La Dev’Team sur MSDN       Retrouver nos experts       L’IT Team sur TechNet
          http://aka.ms/devteam           Microsoft             http://aka.ms/itteam

C# et .NET : Enigmes et puzzles

  • 1.
    C# et .NET Enigmes et Puzzles Clément Gatin, Luc Vo Van Consultants Dev Microsoft Code / Développement
  • 2.
    Donnez votre avis! Depuis votre smartphone, sur : http://notes.mstechdays.fr De nombreux lots à gagner toutes les heures !!! Claviers, souris et jeux Microsoft… Merci de nous aider à améliorer les TechDays http://notes.mstechdays.fr
  • 3.
    Présentation de MicrosoftEnterprise Services Application Critiques (Tier1) Relation client et ressources (ERP / CRM) Collaboration & social Entreprise Microsoft Support Premier Strategy Consulting Services Productivité dans le Cloud Productivité On Premise Environnement de travail Datacenter et Cloud
  • 4.
    4 ouvrages écritspar 13 Microsoftees http://www.editions-eyrolles.com/livres/Windows-8-pour-les-professionnels
  • 5.
    Agenda Introduction et objectifs Lesénigmes 1. Typage explicite (ou pas) 2. Plus Plus 3. Remise à Zéro 4. (D)étonnante combinaison 5. C# dans tous ses états 6. Bouquet final
  • 6.
  • 7.
    Pourquoi cette session? Approfondir la connaissance d’un outil fondamental Apprécier la sophistication du compilateur Repartir avec quelques bonnes pratiques Se tester !
  • 8.
    Visual C# Historique enbref Spécifications du langage
  • 9.
    Enigme 0 :Où trouver la spécification ? A. Sur Internet B. Sur le blog d’Anders Hejlsberg C. Je l’ai toujours sur moi D. Dans l’aide F1 de Visual Studio
  • 10.
    Enigme 0 :Où trouver la spécification ? A. Sur Internet B. Sur le blog d’Anders Hejlsberg C. Je l’ai toujours sur moi D. Dans l’aide F1 de Visual Studio C:Program Files (x86)Microsoft Visual Studio 11.0VC#Specifications
  • 11.
    Visual C# Historique enbref Spécifications du langage ILDASM
  • 12.
    Merci d’être venussi nombreux ! this.Warrior = true; C’est parti.
  • 13.
  • 14.
  • 15.
    Enigme 1 :Quel mot clé est recommandé ? A. Typage explicite B. var C. Aucun
  • 16.
    Enigme 1 :Quel mot clé est recommandé ? A. Typage explicite B. var C. Aucun
  • 17.
    En synthèse ILDASM (IntermediateLanguage Disassembler) est livré avec Visual Studio et permet de parcourir l’IL var ou déclaration explicite : c’est pareil var != dynamic. Réservez dynamic à l’interop !
  • 18.
  • 19.
  • 20.
    Enigme 2 :Qu’affiche le programme ? A. 1 B. 2 C. Ne compile pas
  • 21.
    Enigme 2 :Qu’affiche le programme ? A. 1 B. 2 C. Ne compile pas
  • 22.
    En synthèse C# spécifieles comportements de manière détaillée C’est la fin de l’échauffement !
  • 23.
  • 24.
  • 25.
    La pile (stack) static void Main() { FaitQqch(); FaitAutreChose(); }
  • 26.
    La pile (stack) static void Main() { FaitQqch(); FaitAutreChose(); } Main
  • 27.
    La pile (stack) static void Main() { FaitQqch(); FaitAutreChose(); FaitQqch } Main
  • 28.
    La pile (stack) static void Main() { FaitQqch(); FaitAutreChose(); FaitAutreChose } Main
  • 29.
    La pile (stack) static void Main() { FaitQqch(); FaitAutreChose(); } Main
  • 30.
  • 31.
    Le tas (heap) User utilisateur = new User();
  • 32.
    Le tas (heap) User utilisateur = new User(); utilisateur.Name = "Luc"; Luc
  • 33.
    Le tas (heap) DateTime lucBirth = new DateTime(1979, 11, 28); Luc 28/11 /1978
  • 34.
    Le tas (heap) DateTime lucBirth = new DateTime(1979, 11, 28); utilisateur.BirthDate = lucBirth; 28/11 /1978 Luc 28/11 /1978
  • 35.
    Le tas (heap) DateTime lucBirth = new DateTime(1979, 11, 28); utilisateur.BirthDate = lucBirth; 28/11 /1978 Luc 28/11 /1978
  • 36.
  • 37.
    { Remise àZéro }
  • 38.
    Enigme 3 :Est-ce que ça compile ? A. Oui B. Non C. Ca dépend des options du compilateur D. Ca veut dire quoi « ça compile » ?
  • 39.
    Enigme 3 :Est-ce que ça compile ? A. Oui B. Non C. Ca dépend des options du compilateur D. Ca veut dire quoi « ça compile » ?
  • 40.
    En synthèse Le compilateursait (assez) bien déterminer si les chemins de construction initialisent tous les membres C’est un mécanisme fondamental du déterminisme de .NET :this() permet d’enchaîner les ctor pour les objets complexes this = new peut impressionner en soirée - 40
  • 41.
    (petit) rappel DANS LESCOULISSES DES PROPRIÉTÉS
  • 42.
  • 43.
  • 44.
  • 45.
    Enigme 4 :Qu’affiche le programme ? A. False, False B. False, True C. False, NullReferenceException D. La réponse D
  • 46.
    Enigme 4 :Qu’affiche le programme ? A. False, False B. False, True C. False, NullReferenceException D. La réponse D
  • 47.
    En synthèse Performance surles objets valeurs Pas de garbage collection Pas d’indirection de pointeur Les objets valeurs sont manipulés par copie, donc Attention aux mises à jour Les copies sont consommatrices en performance et en mémoire. 10 appels imbriqués = 10 copies = 10x en RAM La copie de valeur peut engendrer des bugs difficiles à diagnostiquer - 47
  • 48.
    Préconisations Utilisez les structspour des objets de petite taille Evitez les confusions en n’ayant que des structs dont les champs sont en lecture seule - 48
  • 49.
    Enigme 5 C# DANSTOUS SES ÉTATS
  • 50.
    { C# danstous ses états } yield return
  • 51.
    Enigme 5 :Qu’affiche ce programme A. Nom1, Nom2, Clement, Luc B. Nom1, Clement, Nom2, Luc C. Clement, Luc D. Nom1, Nom2
  • 52.
    Enigme 5 :Qu’affiche ce programme A. Nom1, Nom2, Clement, Luc B. Nom1, Clement, Nom2, Luc C. Clement, Luc D. Nom1, Nom2
  • 53.
    Une machine àétats ? 4 2 1 3 5 Une machine à états est un ensemble d’états n et de transitions - 53
  • 54.
    Une machine àétats ? public static IEnumerable<string> GetNames() { 1 Console.WriteLine("Nom 1"); yield return "Clement"; 2 Console.WriteLine("Nom 2"); yield return "Luc"; 3 } - 54
  • 55.
    yield return Chaque yieldreturn correspond à un état Le code entre deux yield return correspond à une transition Le compilateur créé une classe machine à états MoveNext passe à l’état suivant L’état en cours est sauvegardé Les variables locales de la fonctions sont des membres Chaque appel de MoveNext fait un Goto - 55
  • 56.
    { C# danstous ses états } async await
  • 57.
    async await Chaque appelà une méthode préfixée de await est un état Le code entre deux appels est une transition Lors d’un appel à une méthode async, si après l’appel celle si n’est pas terminée (IsCompleted = false), un « awaiter » est créé, qui rappellera la machine à état à la fin de la tâche, pour continuer à l’état courant - 57
  • 58.
    En synthèse Le compilateurgénère des machines à état, qui permettent d’implémenter les scénarios de « reprise » yield return et async sont des constructions bien plus sophistiquées qu’elles n’en ont l’air L’intelligence et la quantité de code fournie par le compilateur est appréciable… et permet d’être plus productif - 58
  • 59.
  • 60.
  • 61.
    Enigme 6 :Qu’affiche ce programme A. Alice a 10 ans, Bob a 11 ans, Charlie a 12 ans, Dave a 13 ans B. Alice a 10 ans, Alice a 10 ans, Alice a 10 ans, Alice a 10 ans C. Dave a 13 ans, Dave a 13 ans, Dave a 13 ans, Dave a 13 ans D. Ne compile pas
  • 62.
    Enigme 6 :Qu’affiche ce programme A. Alice a 10 ans, Bob a 11 ans, Charlie a 12 ans, Dave a 13 ans B. Alice a 10 ans, Alice a 10 ans, Alice a 10 ans, Alice a 10 ans C. Dave a 13 ans, Dave a 13 ans, Dave a 13 ans, Dave a 13 ans D. Ne compile pas
  • 63.
    { Bouquet final} « The Encore »
  • 64.
    Enigme 6 :Qu’affiche ce programme A. Alice a 10 ans, Bob a 11 ans, Charlie a 12 ans, Dave a 13 ans B. Alice a 10 ans, Alice a 10 ans, Alice a 10 ans, Alice a 10 ans C. Dave a 13 ans, Dave a 13 ans, Dave a 13 ans, Dave a 13 ans D. Ne compile pas
  • 65.
    class Main_Scope2 class Main_Scope1 { { string name; Visual Studio 2012 string messageFormat; Main_Scope1 parentScope; List<Action> actions; } } static string[] _Names = new[] { "Alice", "Bob", "Charlie" }; static void Main(string[] args) { string messageFormat = "Hello {0}"; messageFormat = "Hello {0}" List<Action> actions = new List<Action>(); actions = { } for (int i = 0; i < _Names.Length; ++i) { string name = _Names[i]; actions.Add(() => Console.WriteLine(messageFormat, name)); } parentScope parentScope parentScope foreach (var action in actions) Name = Name = Name = action(); "Alice" "Bob" "Charlie" Console.ReadLine(); } Action Action Action
  • 66.
    class Main_Scope1 class Main_Scope2 { { string messageFormat; Visual Studio ≤ 2010 List<Action> actions; } Main_Scope1 parentScope; string name; } static string[] _Names = new[] { "Alice", "Bob", "Charlie" }; static void Main(string[] args) { messageFormat = "Hello {0}" string messageFormat = "Hello {0}"; actions = { } List<Action> actions = new List<Action>(); name ="Charlie" string name; for (int i = 0; i < _Names.Length; ++i) { name = _Names[i]; actions.Add(() => Console.WriteLine(messageFormat, name)); } parentScope parentScope parentScope foreach (var action in actions) action(); Console.ReadLine(); } Action Action Action
  • 67.
    En synthèse Les closuressont un outil pratique et élégant dont la mécanique est implémentée par le compilateur Les breaking changes au niveau compilation sont extrêmement rares, et sont pris très au sérieux par Microsoft - 67
  • 68.
  • 69.
    En synthèse Les évolutionsdu langage C# sont principalement liées au compilateur lui-même, avec peu de support spécifique de la CLR Parti d’une programmation purement itérative proche du langage machine, le C# permet aujourd’hui d’exprimer élégamment des principes complexes par la génération de code Asynchronisme Closures Générateurs - 69
  • 70.
    Pour finir http://notes.mstechdays.fr int i = 0; Console.Write(string.Format("{0} {1} {2} {3}", ++i, i++ * ++i, i, i++ + i++));
  • 71.
    Donnez votre avis! Depuis votre smartphone, sur : http://notes.mstechdays.fr De nombreux lots à gagner toutes les heures !!! Claviers, souris et jeux Microsoft… Merci de nous aider à améliorer les TechDays http://notes.mstechdays.fr
  • 72.
    Développeurs Pros de l’IT http://aka.ms/generation-app Formez-vous en ligne www.microsoftvirtualacademy.com http://aka.ms/evenements- developpeurs Retrouvez nos évènements http://aka.ms/itcamps-france Les accélérateurs Faites-vous accompagner Windows Azure, Windows Phone, gratuitement Windows 8 Essayer gratuitement nos http://aka.ms/telechargements solutions IT La Dev’Team sur MSDN Retrouver nos experts L’IT Team sur TechNet http://aka.ms/devteam Microsoft http://aka.ms/itteam

Notes de l'éditeur

  • #2 Intro code / dev
  • #3 Notation
  • #5 http://www.editions-eyrolles.com/livres/Windows-8-pour-les-professionnels/
  • #9 [Luc]2001 avec .NET 1.0Conçu sur mesure pour la nouvelle CLR
  • #12 [Luc]2001 avec .NET 1.0Conçu sur mesure pour la nouvelle CLR
  • #13 [Luc]Prévu pour une centaine de personnesMontée progressive en sophistication dans les énigmesOn a pas pu upgrader les goodies
  • #25 Clément
  • #26 Clément
  • #41 Luc
  • #48 Luc
  • #49 Luc
  • #58 Clement
  • #59 Clément
  • #66 Version VS2010
  • #67 Version VS2012
  • #72 Notation