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.

qinking126
sumber
3
Enum.IsDefinedtidak baik?
leppie

Jawaban:

155

Kamu bisa memakai:

 Enum.IsDefined(typeof(Age), youragevariable)
AaronS
sumber
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 
}
John Koerner
sumber
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
}
Omar
sumber
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 _);
}
Andy
sumber
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
}
Viacheslav Smityukh
sumber
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; }
}
jwsadler.dll
sumber
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.

agen-j
sumber
2
Harus menggunakan TryParse karena itu input yang belum diverifikasi.
Pelayanan
1
MessageBox tidak masuk akal di lingkungan web.
Pelayanan