Wie überprüfe ich, ob der Zeichenfolgenwert in der Aufzählungsliste enthalten ist?


91

In meiner Abfragezeichenfolge habe ich eine Altersvariable ?age=New_Born.

Gibt es eine Möglichkeit, zu überprüfen, ob dieser Zeichenfolgenwert New_Bornin meiner Aufzählungsliste enthalten ist?

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

Ich könnte jetzt die if-Anweisung verwenden, aber wenn meine Enum-Liste größer wird. Ich möchte einen besseren Weg finden, dies zu tun. Ich denke darüber nach, Linq zu verwenden, bin mir aber nicht sicher, wie ich es machen soll.


2
Enum.IsDefinednicht ok?
Leppie

Antworten:


152

Sie können verwenden:

 Enum.IsDefined(typeof(Age), youragevariable)

IsDefined erfordert Enum Instanz zu überprüfen
Viacheslav Smityukh

9
Denken Sie daran, dass zwischen Enum.IsDefined()Groß- und Kleinschreibung unterschieden wird! Das ist also keine "universelle Lösung".
Cheshire Cat

6
Es wird normalerweise empfohlen, IsDefined nicht zu verwenden, da Is Reflection verwendet und ein Aufruf von IsDefined in Bezug auf Leistung und CPU ein sehr teurer Anruf ist. Verwenden Sie stattdessen TryParse. (gelernt von pluralsight.com)
Weihui Guo

40

Sie können die Enum.TryParse-Methode verwenden:

Age age;
if (Enum.TryParse<Age>("New_Born", out age))
{
    // You now have the value in age 
}

5
Dies ist nur verfügbar ab .NET 4
Gary Richter

2
Das Problem dabei ist, dass es true zurückgibt, wenn Sie eine beliebige Ganzzahl angeben (anstelle Ihrer Zeichenfolge "New_Born", meine ich).
Romain Vincent

10

Sie können die TryParse- Methode verwenden, die bei Erfolg true zurückgibt:

Age age;

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

2

Ich habe eine praktische Erweiterungsmethode, die TryParse verwendet, da bei IsDefined zwischen Groß- und Kleinschreibung unterschieden wird.

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

1

Sie sollten Enum.TryParse verwenden, um Ihr Ziel zu erreichen

Dies ist ein Beispiel:

[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
}

1

Ich weiß, dass dies ein alter Thread ist, aber hier ist ein etwas anderer Ansatz, bei dem Attribute für die Aufzählungen und dann eine Hilfsklasse verwendet werden, um die passende Aufzählung zu finden.

Auf diese Weise können Sie mehrere Zuordnungen für eine einzelne Aufzählung haben.

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
}

Mit meiner Helferklasse so

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();
    }

}

Sie können dann so etwas tun

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

Und der Vollständigkeit halber hier das 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; }
}

0

Um das Alter zu analysieren:

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

Um zu sehen, ob es definiert ist:

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

Je nachdem, wie Sie die AgeAufzählung verwenden möchten, sind Flags möglicherweise nicht das Richtige. Wie Sie wahrscheinlich wissen, [Flags]gibt dies an, dass Sie mehrere Werte zulassen möchten (wie in einer Bitmaske). IsDefinedwird false zurückgeben, Age.Toddler | Age.Preschoolda es mehrere Werte hat.


2
Sollte TryParse verwenden, da es sich um eine nicht überprüfte Eingabe handelt.
Servy

1
MessageBox ist in einer Webumgebung nicht wirklich sinnvoll.
Servy
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.