Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Cyril Sansus

WPF, Interfaces Utilisateurs et .NET
Enum.TryParse ?

Alors qu’on peut trouver int.TryParse, DateTime.TryParse dans le Framework .NET, la méthode Enum.TryParse n’existe pas.

La méthode intuitivement utilisée pour essayer de convertir une chaîne de caractères en une Enum est la suivante  :

   1: public static bool TryParse(String value, out T result)
   2: {
   3:     result = default(T);
   4:     try
   5:     {
   6:         result = (T) Enum.Parse(typeof(T), value, true);
   7:         return true;
   8:     }
   9:     catch
  10:     {
  11:         return false;
  12:     }
  13: }

L’inconvénient d’utiliser la méthode Enum.Parse lorsque la conversion n’est pas possible est que l’exécution est très très très lente ! L’exemple suivant met environ 2 secondes pour s’exécuter :

   1: for (int i = 0; i < 1000; i++)
   2: {
   3:     TryParse ("Hello !", out result);
   4: }

Tout ca pour dire, que cette méthode peut s’avérer inutilisable dans certains cas. En fait ce qui est lent dans cette méthode, c’est le simple fait de lever une exception pour dire que la conversation a échoué (lever une exception c’est mou et c’est pour cela que ça doit rester exceptionnel).

Pour contourner le problème il existe différentes méthodes que vous trouverez un peu partout sur la toile. Attention, sachez que Enum.Parse gère TOUS les cas figures :

  • Remplacement de certaines caractères spéciaux (+,-, _)
  • Gestion des Flags
  • Gestion de la case

Ceci n’est pas forcement vrai des méthodes que vous allez trouver ! Pour ma part, j’ai opté pour la solution simple qui ne gère même pas la case :

   1: public static bool TryParse(string valueToParse, out T returnValue)
   2: {
   3:     returnValue = default(T);
   4:     if (Enum.IsDefined(typeof(T), valueToParse))
   5:     {
   6:         returnValue = (T)Enum.Parse(typeof(T),valueToParse);
   7:         return true;
   8:     }
   9:     return false;
  10: }

A noter, que si je refais le précédent test cette méthode ne mettra que 1 milliseconde.

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :
Posted: mercredi 2 septembre 2009 08:00 par Vko

Commentaires

FREMYCOMPANY a dit :

Quelle différence énorme en effet...

# septembre 2, 2009 09:31

Graveen a dit :

Excellent, j'étais - justement - en train de réfléchir sur le sujet.

# septembre 2, 2009 09:53

lionel.limozin a dit :

Et pourquoi pas mettre ta methode en tant que methode d'extension ? ça fera plus classe et ça paraitra preque standard ;)

# septembre 2, 2009 13:44

Vko a dit :

C'est une très bonne remarque, mais il fallait bien que ne fasse pas tout :)

# septembre 2, 2009 14:36

patrice a dit :

A noter que le cout en performance de la première solution proposée n'est pas uniquement dû à la levée d'exception mais bien à "l'écoute" via le bloc Try. Qu'il y ait des exceptions de levées ou non, l'utilisation d'un bloc Try est couteuse en terme de perf.

# septembre 2, 2009 14:59

smo a dit :

L'inconvénient de IsDefined c'est qu'il ne gère pas les enums Flags, les int, etc...

PS1: sur ma machine je ne trouve qu'un facteur de 100 entre les deux versions (ce qui est déjà beaucoup)

PS2: Le coût du try/catch est quasiment nul, tant qu'aucune exception n'est levée (cf http://blogs.msdn.com/ricom/archive/2003/12/19/44697.aspx).

# septembre 2, 2009 22:21

Vko a dit :

Oui comme je l'ai indiqué, la solution choisie est la plus basique. Pour faire une solution prenant tous les cas, il "suffit" de prendre Reflector et d'enlever "simplement" l'exception.

J'ai effectué les tests sur un Intel Duo 2,2Ghz avec 3Go de ram.

# septembre 4, 2009 12:32
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Kinect 1.5 is out ! par Cyril Sansus le 05-21-2012, 17:47

- Les actualités de la semaine sur c2i.fr (14 mai - 20 mai) par Richard Clark le 05-21-2012, 08:50

- Reactive Extensions : Consommer des services avec Rx Partie 3, les pièges à éviter par Léonard Labat le 05-20-2012, 23:45

- SharePoint Blog Site, problème d’archives par Le Blog (Vert) d'Arnaud JUND le 05-20-2012, 13:09

- Soirée ALT.NET Mai - 3 présentations par #Rui le 05-18-2012, 11:59

- [ #SharePoint 2010][ #SQLServer 2012] AlwaysOn pour SharePoint (2/4) : Configuration (2e partie)… par Le blog de Patrick [MVP SharePoint] le 05-18-2012, 11:31

- Team Foundation Server 11: tous les trésors cachés du site d’équipe par Philess le 05-16-2012, 19:01

- [PowerShell 3] Télécharger et installer la documentation en ligne par Blog de SPBrouillet (Pierrick BROUILLET) le 05-16-2012, 17:36

- [#SharePoint 2010][#SQLServer 2012] AlwaysOn pour SharePoint (1/4) : Configuration (1ère partie)… par Le blog de Patrick [MVP SharePoint] le 05-16-2012, 12:10

- Job Day @MIC Brussels - .Net Developers on Mobile applications par Le Blog (Vert) d'Arnaud JUND le 05-15-2012, 20:26