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?
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);
}
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.
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;
}
}
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);
}
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.