bagaimana cara memeriksa apakah nilai string ada dalam daftar Enum?


92

Dalam string kueri saya, saya memiliki variabel usia ?age=New_Born.

Apakah ada cara saya dapat memeriksa apakah nilai string ini New_Bornada dalam daftar Enum saya

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

Saya dapat menggunakan pernyataan if untuk saat ini, tetapi jika daftar Enum saya bertambah besar. Saya ingin menemukan cara yang lebih baik untuk melakukannya. Saya sedang berpikir untuk menggunakan LINQ, hanya saja tidak yakin bagaimana melakukannya.


3
Enum.IsDefinedtidak baik?
leppie

Jawaban:


155

Kamu bisa memakai:

 Enum.IsDefined(typeof(Age), youragevariable)

IsDefined membutuhkan contoh Enum untuk diperiksa
Viacheslav Smityukh

9
Ingatlah bahwa Enum.IsDefined()peka huruf besar / kecil! Jadi itu bukan "solusi universal".
Cheshire Cat

7
Biasanya disarankan agar IsDefined tidak digunakan, karena Is menggunakan refleksi, membuat panggilan ke IsDefined merupakan panggilan yang sangat mahal dalam hal performa dan CPU. Gunakan TryParse sebagai gantinya. (belajar dari pluralsight.com)
Weihui Guo

41

Anda dapat menggunakan metode Enum.TryParse:

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

5
Ini hanya tersedia mulai .NET 4
Gary Richter

2
Masalah dengan ini adalah bahwa itu akan mengembalikan true jika Anda memberikan bilangan bulat APAPUN (bukan string "New_Born" Anda, maksud saya).
Romain Vincent

10

Anda dapat menggunakan metode TryParse yang mengembalikan nilai true jika berhasil:

Age age;

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

2

Saya punya metode ekstensi praktis yang menggunakan TryParse, karena IsDefined peka huruf besar / kecil.

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

1

Anda harus menggunakan Enum.TryParse untuk mencapai tujuan Anda

Ini contohnya:

[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

Saya tahu ini adalah utas lama, tetapi inilah pendekatan yang sedikit berbeda menggunakan atribut pada Enumerates dan kemudian kelas penolong untuk menemukan enumerate yang cocok.

Dengan cara ini Anda bisa memiliki beberapa pemetaan pada satu pencacahan.

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
}

Dengan kelas pembantu saya seperti ini

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

}

Anda kemudian dapat melakukan sesuatu seperti

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

Dan untuk kelengkapannya inilah atributnya:

 [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

Untuk mengurai usia:

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

Untuk melihat apakah itu sudah ditentukan:

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

Bergantung pada bagaimana Anda berencana menggunakan Ageenum, flag mungkin bukan hal yang benar. Seperti yang mungkin Anda ketahui, [Flags]menunjukkan bahwa Anda ingin mengizinkan beberapa nilai (seperti dalam bit mask). IsDefinedakan mengembalikan false Age.Toddler | Age.Preschoolkarena memiliki beberapa nilai.


2
Harus menggunakan TryParse karena itu input yang belum diverifikasi.
Pelayanan

1
MessageBox tidak masuk akal di lingkungan web.
Pelayanan
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.