comment vérifier si la valeur de la chaîne est dans la liste Enum?

91

Dans ma chaîne de requête, j'ai une variable d'âge ?age=New_Born.

Existe-t-il un moyen de vérifier si cette valeur de chaîne New_Bornest dans ma liste Enum

[Flags]
public enum Age
{
    New_Born = 1,
    Toddler = 2,
    Preschool = 4,
    Kindergarten = 8
}

Je pourrais utiliser l'instruction if pour le moment, mais si ma liste Enum s'agrandit. Je veux trouver une meilleure façon de le faire. Je pense utiliser Linq, mais je ne sais pas comment le faire.

qinking126
la source
2
Enum.IsDefinedpas d'accord?
leppie

Réponses:

153

Vous pouvez utiliser:

 Enum.IsDefined(typeof(Age), youragevariable)
AaronS
la source
IsDefined nécessite une instance Enum pour vérifier
Viacheslav Smityukh
9
N'oubliez pas que Enum.IsDefined()c'est sensible à la casse! Ce n'est donc pas une «solution universelle».
Cheshire Cat
6
Il est normalement recommandé de ne pas utiliser IsDefined, car Is utilise la réflexion, faisant un appel à IsDefined un appel très coûteux en termes de performances et de CPU. Utilisez TryParse à la place. (appris de pluralsight.com)
Weihui Guo
40

Vous pouvez utiliser la méthode Enum.TryParse:

Age age;
if (Enum.TryParse<Age>("New_Born", out age))
{
    // You now have the value in age 
}
John Koerner
la source
5
Ceci n'est disponible qu'à partir de .NET 4
Gary Richter
2
Le problème avec ceci est qu'il retournera vrai si vous fournissez N'IMPORTE QUEL entier (au lieu de votre chaîne "New_Born", je veux dire).
Romain Vincent
10

Vous pouvez utiliser la méthode TryParse qui renvoie true si elle réussit:

Age age;

if(Enum.TryParse<Age>("myString", out age))
{
   //Here you can use age
}
Omar
la source
2

J'ai une méthode d'extension pratique qui utilise TryParse, car IsDefined est sensible à la casse.

public static bool IsParsable<T>(this string value) where T : struct
{
    return Enum.TryParse<T>(value, true, out _);
}
Andy
la source
1

Vous devez utiliser Enum.TryParse pour atteindre votre objectif

Voici un exemple:

[Flags]
private enum TestEnum
{
    Value1 = 1,
    Value2 = 2
}

static void Main(string[] args)
{
    var enumName = "Value1";
    TestEnum enumValue;

    if (!TestEnum.TryParse(enumName, out enumValue))
    {
        throw new Exception("Wrong enum value");
    }

    // enumValue contains parsed value
}
Viacheslav Smityukh
la source
1

Je sais que c'est un ancien thread, mais voici une approche légèrement différente utilisant des attributs sur les Enumerates, puis une classe d'assistance pour trouver l'énumération qui correspond.

De cette façon, vous pouvez avoir plusieurs mappages sur une seule énumération.

public enum Age
{
    [Metadata("Value", "New_Born")]
    [Metadata("Value", "NewBorn")]
    New_Born = 1,
    [Metadata("Value", "Toddler")]
    Toddler = 2,
    [Metadata("Value", "Preschool")]
    Preschool = 4,
    [Metadata("Value", "Kindergarten")]
    Kindergarten = 8
}

Avec ma classe d'aide comme ça

public static class MetadataHelper
{
    public static string GetFirstValueFromMetaDataAttribute<T>(this T value, string metaDataDescription)
    {
        return GetValueFromMetaDataAttribute(value, metaDataDescription).FirstOrDefault();
    }

    private static IEnumerable<string> GetValueFromMetaDataAttribute<T>(T value, string metaDataDescription)
    {
        var attribs =
            value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof (MetadataAttribute), true);
        return attribs.Any()
            ? (from p in (MetadataAttribute[]) attribs
                where p.Description.ToLower() == metaDataDescription.ToLower()
                select p.MetaData).ToList()
            : new List<string>();
    }

    public static List<T> GetEnumeratesByMetaData<T>(string metadataDescription, string value)
    {
        return
            typeof (T).GetEnumValues().Cast<T>().Where(
                enumerate =>
                    GetValueFromMetaDataAttribute(enumerate, metadataDescription).Any(
                        p => p.ToLower() == value.ToLower())).ToList();
    }

    public static List<T> GetNotEnumeratesByMetaData<T>(string metadataDescription, string value)
    {
        return
            typeof (T).GetEnumValues().Cast<T>().Where(
                enumerate =>
                    GetValueFromMetaDataAttribute(enumerate, metadataDescription).All(
                        p => p.ToLower() != value.ToLower())).ToList();
    }

}

vous pouvez alors faire quelque chose comme

var enumerates = MetadataHelper.GetEnumeratesByMetaData<Age>("Value", "New_Born");

Et pour être complet, voici l'attribut:

 [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = true)]
public class MetadataAttribute : Attribute
{
    public MetadataAttribute(string description, string metaData = "")
    {
        Description = description;
        MetaData = metaData;
    }

    public string Description { get; set; }
    public string MetaData { get; set; }
}
jwsadler
la source
0

Pour analyser l'âge:

Age age;
if (Enum.TryParse(typeof(Age), "New_Born", out age))
  MessageBox.Show("Defined");  // Defined for "New_Born, 1, 4 , 8, 12"

Pour voir s'il est défini:

if (Enum.IsDefined(typeof(Age), "New_Born"))
   MessageBox.Show("Defined");

Selon la façon dont vous prévoyez d'utiliser l' Ageénumération, les indicateurs peuvent ne pas être la bonne chose. Comme vous le savez probablement, [Flags]indique que vous souhaitez autoriser plusieurs valeurs (comme dans un masque de bits). IsDefinedrenverra false car Age.Toddler | Age.Preschoolcar il a plusieurs valeurs.

agent-j
la source
2
Devrait utiliser TryParse car il s'agit d'une entrée non vérifiée.
Servy
1
MessageBox n'a pas vraiment de sens dans un environnement Web.
Servy