web-dev-qa-db-fra.com

Version générique de Enum.Parse en C #

Je me suis régulièrement demandé pourquoi C # n'avait pas encore implémenté un Enum.Parse générique.

Disons que j'ai

enum MyEnum
{
   Value1,
   Value2
}

Et à partir d’un fichier XML/d’une entrée de base de données, je souhaite créer un Enum.

MyEnum val = (MyEnum)Enum.Parse(typeof(MyEnum), "value1", true);

N'aurait-il pas pu être implémenté comme quelque chose comme

MyEnum cal = Enum.Parse<MyEnum>("value1");

Cela peut sembler être un petit problème, mais cela semble être négligé.

Des pensées?

39
Adriaan Stander

Il est déjà implémenté dans .NET 4;) Regardez ici .

MyEnum cal;
if (!Enum.TryParse<MyEnum>("value1", out cal))
   throw new Exception("value1 is not valid member of enumeration MyEnum");

La discussion ici contient également des points intéressants.

34
Tomas Vana

Et dans la syntaxe souhaitée de la question:

MyEnum cal = Toolkit.Parse<MyEnum>("value1");

Remarque : Etant donné que C # vous interdit d'ajouter des extensions statiques, vous devez héberger la fonction ailleurs. J'utilise une classe Toolkit statique qui contient tous ces bits utiles:

/// <summary>
/// Converts the string representation of the name or numeric value of one or
//  more enumerated constants to an equivalent enumerated object.
/// </summary>
/// <typeparam name="TEnum">An enumeration type.</typeparam>
/// <param name="value">A string containing the name or value to convert.</param>
/// <returns>An object of type TEnum whose value is represented by value</returns>
/// <exception cref="System.ArgumentNullException">enumType or value is null.</exception>
/// <exception cref=" System.ArgumentException"> enumType is not an System.Enum. -or- 
/// value is either an empty string or only contains white space.-or- 
/// value is a name, but not one of the named constants defined for the enumeration.</exception>
/// <exception cref="System.OverflowException">value is outside the range of the underlying type of enumType.</exception>
public static TEnum Parse<TEnum>(String value) where TEnum : struct
{
   return (TEnum)Enum.Parse(typeof(TEnum), value);
}
16
Ian Boyd

Bien que contraindre à System.Enum ne soit pas autorisé par C #, il est autorisé dans .NET et C # peuvent use types ou méthodes avec de telles contraintes. Voir la bibliothèque Unconstrained Melody de Jon Skeet, qui inclut du code qui fait exactement ce que vous voulez.

6
kvb
public class EnumHelper
{
    public static T? TryParse<T>(string text)
        where T: struct
    {
        if (string.IsNullOrEmpty(text))
        {
            return null;
        }

        T r;

        if (Enum.TryParse<T>(text, out r))
        {
            return r;
        }

        return null;
    }
}
2
user2397863

Version légèrement modifiée de la réponse de @ ian-boyd, utilisant une méthode d'extension pour éviter d'avoir à spécifier un nom de classe statique dans l'appel:

MyEnum cal = "value1".Parse<MyEnum>();

/// <summary>
/// Converts the string representation of the name or numeric value of one or
//  more enumerated constants to an equivalent enumerated object.
/// </summary>
/// <typeparam name="TEnum">An enumeration type.</typeparam>
/// <returns>An object of type TEnum whose value is represented by value</returns>
/// <exception cref="System.ArgumentNullException">enumType or value is null.</exception>
/// <exception cref=" System.ArgumentException"> enumType is not an System.Enum. -or- 
/// value is either an empty string or only contains white space.-or- 
/// value is a name, but not one of the named constants defined for the enumeration.</exception>
/// <exception cref="System.OverflowException">value is outside the range of the underlying type of enumType.</exception>
public static TEnum Parse<TEnum>(this String value) where TEnum : struct
{
   return (TEnum)Enum.Parse(typeof(TEnum), value);
}
1
Jimmy

Tout en peaufinant un peu avec certaines méthodes, en essayant de construire quelque chose de similaire à la proposition initiale:

MyEnum cal = Enum.Parse<MyEnum>("value1");

il me semblait que cette syntaxe ne serait pas possible en C #, car le type Enum est traité comme non nullable.

Si nous appelons la méthode "Enum.TryParse" en transmettant une valeur ne correspondant pas à un élément de l’énum, ​​la valeur par défaut d’Enum sera renvoyée dans la variable "out". C’est pourquoi nous devons d’abord tester le résultat "Enum.TryParse", puisqu’il suffit d’appeler

MyEnum cal;
Enum.TryParse<MyEnum>("value1", out cal);

et vérifier la valeur "cal" ne donnera pas toujours un résultat fiable.

0
Jose Tepedino