jeudi 21 janvier 2010

Support des Sets et test d'inclusion en C#

Au cours d'une séance d'exploration sur la classe XmlReader en C#, je suis arrivé à un point où il me fallait écrire un traitement conditionnel dépendant du type de noeud xml (XmlReader.NodeType).

Dans un tout premier temps, j'ai voulu tester si le type de noeud en cours de lecture était une entité Element ou CData.
Cependant, je m'attendais également à devoir rallonger la liste des éléments à supporter dans mon test.
Je me suis donc attardé sur les test d'inclusion.

Coding standard en C#
Le test d'inclusion pouvait s'écrire:
if ((myReader.NodeType == XmlNodeType.Element) || (myReader.NodeType ==XmlNodeType.CDATA) )
doTraitement1();
else
doTraitement2();
Cependant, cette option (tout comme le switch) aura le désavantage de dégrader la lisibilité s'il faut étendre le test pour supporter de nouvelles valeurs.

Coding en Delphi
Delphi (tout comme Sql ou Python) supporte la notion d'ensemble (les Sets).
Delphi offre par ailleurs la possibilité d'effectuer des tests d'inclusion sur un paramètre à l'aide de ces ensembles.
C'est ainsi que le test d'inclusion suivant est tout à fait valable en Delphi.
if FieldType in [DataType_Numeric, DataType_Text] then 
doTraitement1()
else
doTraitement2() 

Une approche LinQ en C#
Je n'ai malheureusement pas encore trouvé d'écriture similaire à celle de Delphi pour C#.
Cependant, LinQ et les generics offrent la possibilité d'écrire des tests d'inclusion.
Le but étant de construire une collection contenant les valeurs admises et de vérifier si cette collection contient le paramètre à tester.
L'exemple ci-dessous démontre ce principe.
...
XmlTextReader myReader = new XmlTextReader(myFile);

if (
   (new List<XmlNodeType>(){ XmlNodeType.Element, XmlNodeType.CDATA }).Contains( myReader.NodeType ) )
  Console.WriteLine("myReader.ReadContentAsString = " + myReader.ReadContentAsString() );

Ajouter le support des Set à C#
Parmi tous les dérivés des collections, C# (jusqu'à la version 3.5 du Framework) ne dispose pas de structure de type Set.
Un set dispose des fonctionnalités suivantes:
  • Un set contient une liste d'élément (chaque élément étant présent une seule fois).
  • Le traitement des Set est rapide.
  • Les Set disposent d'opération d'inclusion, union, intersection, de test, etc.
  • Les Set disposent d'opérateurs permettant un codage clair et efficace.
Si C# manque cruellement de Set, l'article "Add Support for "Set" Collections to .NET" sur "The Code Project" essaye de résoudre ce problème avec un certain brio.
A côté des développement sur "The Code Project", il existe également la collection de classe C5.

Support des Set pour .Net 3.5
En information de dernière minute, il semblerait qu'il existerait une classe HashSet() à partir de la version 3.5 du framework
Je vais me pencher un peu la dessus...

Aucun commentaire: