Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Vko

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

- L'interface naturelle de Windows Phone 7 Series par Perspective le il y a 49 minutes

- Comment mapper une vue SQL sur une collection de complex type? par Matthieu MEZIL le il y a 22 heures et 32 minutes

- SQL Server : Query Notification ou comment être notifié de modifications de données côté application (SqlDependency) par SQL Server vu par Christian Robert le 03-19-2010, 15:06

- [WF4] Un Binding Activity/ActivityDesigner qui passe mal? par Blog de Jérémy Jeanson le 03-19-2010, 13:42

- MyTIC – SharePoint 2010 : déjà un mythe Microsoft ? par Le Blog (Vert) d'Arnaud JUND le 03-19-2010, 08:54

- TechDays 2010 Genève : Retrouvez-moi pour une session sur la Haute disponibilité et le ScaleOut avec SQL Server par SQL Server vu par Christian Robert le 03-18-2010, 15:45

- [MIX10] Keynote deuxième journée – Internet Explorer 9, Html5, Visual Studio 2010, OData par Atteint de JavaScriptite Aiguë [Cyril Durand] le 03-17-2010, 19:40

- Certifications beta .NET 4 par Kévin Gosse le 03-17-2010, 19:33

- [Mix 2010] – Microsoft Translator Technology Preview V2 par RedoBlog - The .NET Gentleman !!! le 03-17-2010, 18:53

- Lancement en Preview de Cyclone lors des TechDays 2010! par Blog de Frédéric Queudret le 03-17-2010, 16:30