Frédéric Mélantois
C# 3.0 Beta, déclarations et initialisations simplifiées, regardons sous le capot !
Puisque le produit est encore en beta, portons un regard sur quelques nouveautés du langage et ce qui peut être généré par le compilateur c#.
Par Frédéric Mélantois publié le 25/06/2007 à 00:52, lu 4725 fois, 8 pages
 6 | Initialisation de collections
Une écriture simplifiée permet d'initialiser une collection. A priori, un objet implémentant l'interface « IEnumerable » ou « IEnumerable<T> » peut bénéficier de la syntaxe c# 3.0 de la façon suivante :

static void Main(string[] args)

{

    List<int> l = new List<int> { 1, 2, 3, 4};

 

    Console.WriteLine(l[0].ToString());

    Console.ReadLine();

}

ce qui correspond à l'écriture c# 2.0 suivante :

static void Main(string[] args)

{

    List<int> l = new List<int>();

    l.Add(1);

    l.Add(2);

    l.Add(3);

    l.Add(4);

 

    Console.WriteLine(l[0].ToString());

    Console.ReadLine();

}

Si nous analysons le code IL correspondant à la syntaxe simplifiée de c# 3.0, nous observons qu'un appel à la méthode « Add » est fait pour chaque item :

.method private hidebysig static void  Main(string[] args) cil managed

{

  .entrypoint

  .maxstack  2

  .locals init ([0] class [mscorlib]System.Collections.Generic.List`1<int32> l,

           [1] class [mscorlib]System.Collections.Generic.List`1<int32> '<>g__initLocal0',

           [2] int32 CS$0$0000)

  IL_0000:  newobj    instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()

  IL_0005:  stloc.1

  IL_0006:  ldloc.1

  IL_0007:  ldc.i4.1

  IL_0008:  callvirt   instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)

  IL_000d:  ldloc.1

  IL_000e:  ldc.i4.2

  IL_000f:  callvirt   instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)

  IL_0014:  ldloc.1

  IL_0015:  ldc.i4.3

  IL_0016:  callvirt   instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)

  IL_001b:  ldloc.1

  IL_001c:  ldc.i4.4

  IL_001d:  callvirt   instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)

  IL_0022:  ldloc.1

  IL_0023:  stloc.0

  IL_0024:  ldloc.0

  IL_0025:  ldc.i4.0

  IL_0026:  callvirt   instance !0 class [mscorlib]System.Collections.Generic.List`1<int32>::get_Item(int32)

  IL_002b:  stloc.2

  IL_002c:  ldloca.s   CS$0$0000

  IL_002e:  call       instance string [mscorlib]System.Int32::ToString()

  IL_0033:  call       void [mscorlib]System.Console::WriteLine(string)

  IL_0038:  call       string [mscorlib]System.Console::ReadLine()

  IL_003d:  pop

  IL_003e:  ret

}

Remarquez en rouge la variable locale supplémentaire créée ainsi que les deux instructions « inutiles » de chargement et de déchargement dans la pile pour transmettre une référence de l'objet de la variable locale supplémentaire vers la variable que nous avions nommée. Pour les non-initiés à l'IL, l'utilitaire Reflector vous permet de voir ce que génère le compilateur C# :

private static void Main(string[] args)

{

    List<int> <>g__initLocal1 = new List<int>();

    <>g__initLocal1.Add(1);

    <>g__initLocal1.Add(2);

    <>g__initLocal1.Add(3);

    <>g__initLocal1.Add(4);

    List<int> l = <>g__initLocal1;

    Console.WriteLine(l[0].ToString());

    Console.ReadLine();

}

L'implémentation de l'interface IEnumerable est-elle une condition minimale pour pouvoir initialiser une collection ? Il semble bien que non comme le montre le compilateur :
 
/content/f4e62165-4fd8-44cb-9394-f126278221d8/collection.jpg
 
La méthode « Add » semble être indispensable. La lecture des spécifications c# 3.0, chapitre 26.4.2 confirme cette nécessité. Par exemple, les collections implémentant notamment « IList » ou « IDictionnary » répondent à ce critère puisque la méthode « Add » fait partie de ces interfaces et ces dernières implémentent « IEnumerable ».
Vous trouverez des précisions supplémentaires sur le modèle sur ce lien très intéressant que m'a suggéré Mitsu Futura What is a collection ?
La syntaxe d'initialisation des collections de c# 3.0 est séduisante. On doit toutefois garder à l'esprit qu'elle génère une variable locale inutile.
 
» Démarrer une discussion
 
Discussion démarée par Malkuth le 24/07/2007 à 03:11, 2 commentaire(s).
Discussion démarée par vjacquet le 25/06/2007 à 17:42, 4 commentaire(s).