2010-04-16 6 views
5

Je les méthodes suivantes dans une classe d'aide enum (je l'ai simplifié pour la fin de la question):Existe-t-il un meilleur moyen de créer une chaîne de conversion générique en méthode enum ou enum extension?

static class EnumHelper 
{ 
    public enum EnumType1 : int 
    { 
     Unknown = 0, 
     Yes = 1, 
     No = 2 
    } 

    public enum EnumType2 : int 
    { 
     Unknown = 0, 
     Dog = 1, 
     Cat = 2, 
     Bird = 3 
    } 

    public enum EnumType3 
    { 
     Unknown, 
     iPhone, 
     Andriod, 
     WindowsPhone7, 
     Palm 
    } 

    public static EnumType1 ConvertToEnumType1(string value) 
    { 
     return (string.IsNullOrEmpty(value)) ? 
      EnumType1.Unknown : 
      (EnumType1)(Enum.Parse(typeof(EnumType1), value, true)); 
    } 

    public static EnumType2 ConvertToEnumType2(string value) 
    { 
     return (string.IsNullOrEmpty(value)) ? 
      EnumType2.Unknown : 
      (EnumType2)(Enum.Parse(typeof(EnumType2), value, true)); 
    } 

    public static EnumType3 ConvertToEnumType3(string value) 
    { 
     return (string.IsNullOrEmpty(value)) ? 
      EnumType3.Unknown : 
      (EnumType3)(Enum.Parse(typeof(EnumType3), value, true)); 
    } 
} 

La question ici est, je peux couper cela à une méthode d'extension Enum ou peut-être un type de méthode unique qui peut gérer n'importe quel type. J'ai trouvé quelques exemples pour le faire avec des énumérations de base mais la différence dans mon exemple est que tous les enums ont l'élément Unknown que j'ai besoin retourné si la chaîne est nulle ou vide (si aucune correspondance n'est trouvée, je veux qu'elle échoue).

Vous cherchez quelque chose comme ce qui suit peut-être:

EnumType1 value = EnumType1.Convert("Yes"); 
// or 
EnumType1 value = EnumHelper.Convert(EnumType1, "Yes"); 

une fonction à tout faire ... comment gérer l'élément Unknown est la partie que je suis raccroché au nez.

Édition: Ajusté l'une des énumérations à ne pas définir avec des entiers. Donc je peux garantir que 0 sera toujours le cas mais Unknown sera toujours le texte correct ... Je suppose que je pourrais utiliser le même exemple que le T (0) mais faire une autre analyse sur le texte "Inconnu".

Répondre

8

Utilisez ce, en supposant que inconnu est toujours la valeur 0.

public static T ConvertToEnum<T>(this string value) where T : new() 
{ 
    if(!typeof(T).IsEnum) 
     throw new NotSupportedException("T must be an Enum"); 

    try 
    { 
     return (T)Enum.Parse(typeof(T), value); 
    } 
    catch 
    { 
     return default(T); // equivalent to (T)0 
     //return (T)Enum.Parse(typeof(T), "Unknown")); 
    } 
} 

Utilisation:

EnumType2 a = "Cat".ConvertToEnum<EnumType2>(); 
EnumType2 b = "Person".ConvertToEnum<EnumType2>(); // Unknown 

EDIT par OP (Kelsey): Votre réponse me conduire à la bonne réponse, donc je pensais que je l'inclure ici:

public static T ConvertTo<T>(this string value) 
{ 
    T returnValue = (T)(Enum.Parse(typeof(T), "Unknown", true)); 
    if ((string.IsNullOrEmpty(value) == false) && 
     (typeof(T).IsEnum)) 
    { 
     try { returnValue = (T)(Enum.Parse(typeof(T), value, true)); } 
     catch { } 
    } 
    return returnValue; 
} 
+1

La contrainte ne peut pas être de la classe spéciale 'System.Enum' –

+0

@ Maud'Dib: Pouah, tu as raison. Je n'ai pas vu l'erreur dans mon projet fictif. Je vais mettre à jour. – chilltemp

+0

@Kelsey: Votre droit, vous pouvez simplement reparer 'Inconnu' à chaque fois, mais lancer à partir de 0 est plus efficace en supposant que c'est sûr pour vos Enums. – chilltemp

2

génériques d'usage ... quelque chose comme ça ....

public static TResult ConvertTo<TResult>(this string source) 
{ 
    if(!typeof(TResult).IsEnum) 
    { 
     throw new NotSupportedException("TResult must be an Enum"); 
    } 

    if (!Enum.GetNames(typeof(TResult)).Contains(source)) 
     return default(TResult); 


    return (TResult)Enum.Parse(typeof(TResult), source); 
} 

(the code came from here)

+0

Ce que je savait comment faire ... mais comment vais-je récupérer le 'EnumTypeX.Unknown' quand il est vide ou vide? – Kelsey

+2

ajoutez cette ligne ... if (! Enum.GetNames (typeof (TResult)). Contient (source)) return default (TResult); –