Dize değerinin Enum listesinde olup olmadığı nasıl kontrol edilir?


92

Sorgu dizemde yaş değişkenim var ?age=New_Born.

Bu dize değerinin New_BornEnum listemde olup olmadığını kontrol etmemin bir yolu var mı

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

Şu an için if ifadesini kullanabilirim, ancak Enum listem büyürse. Bunu yapmanın daha iyi bir yolunu bulmak istiyorum. Linq'i kullanmayı düşünüyorum ama nasıl yapacağımı bilmiyorum.


3
Enum.IsDefinedTamam değil?
leppie

Yanıtlar:


156

Kullanabilirsiniz:

 Enum.IsDefined(typeof(Age), youragevariable)

IsDefined, kontrol etmek için Enum örneğini gerektirir
Viacheslav Smityukh

9
Bunun Enum.IsDefined()büyük / küçük harfe duyarlı olduğunu unutmayın ! Yani bu "evrensel bir çözüm" değil.
Cheshire Kedisi

7
Normalde IsDefined'ın kullanılmaması tavsiye edilir, çünkü Is yansıma kullanır, IsDefined'a çağrı yapmak performans ve CPU açısından çok pahalı bir çağrıdır. Bunun yerine TryParse kullanın. (pluralsight.com'dan öğrendi)
Weihui Guo

41

Enum. TryParse yöntemini kullanabilirsiniz:

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

5
Bu yalnızca .NET 4'ten itibaren mevcuttur
Gary Richter

2
Bununla ilgili sorun, HERHANGİ bir tamsayı sağlarsanız ("New_Born" dizeniz yerine, yani) true dönecek olmasıdır.
Romain Vincent

11

Başarılı olursa true döndüren TryParse yöntemini kullanabilirsiniz :

Age age;

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

2

IsDefined büyük / küçük harfe duyarlı olduğu için TryParse kullanan kullanışlı bir uzantı yöntemim var.

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

1

Hedefinize ulaşmak için Enum. TryParse kullanmalısınız

Bu bir örnektir:

[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

Bunun eski bir iş parçacığı olduğunu biliyorum, ancak burada, Numaralandırmalar üzerindeki öznitelikleri kullanan biraz farklı bir yaklaşım ve ardından eşleşen numaralandırmayı bulmak için yardımcı bir sınıf var.

Bu şekilde, tek bir numaralandırma üzerinde birden çok eşleştirmeye sahip olabilirsiniz.

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
}

Yardımcı sınıfımla bunun gibi

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

}

o zaman şöyle bir şey yapabilirsin

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

Ve tamlık için buradaki özellik:

 [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

Yaşı ayrıştırmak için:

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

Tanımlanıp tanımlanmadığını görmek için:

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

Numaralamayı nasıl kullanmayı planladığınıza bağlı olarak Age, bayraklar doğru şey olmayabilir. Muhtemelen bildiğiniz gibi, [Flags]birden çok değere izin vermek istediğinizi belirtir (bir bit maskesinde olduğu gibi). birden çok değere sahip olduğu için IsDefinedyanlış döndürür Age.Toddler | Age.Preschool.


2
Doğrulanmamış girdi olduğu için TryParse kullanmalıdır .
Servy

1
MessageBox bir web ortamında gerçekten mantıklı değil.
Servy
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.