làm thế nào để kiểm tra xem giá trị chuỗi có trong danh sách Enum không?


91

Trong chuỗi truy vấn của tôi, tôi có một biến tuổi ?age=New_Born.

Có cách nào tôi có thể kiểm tra xem giá trị chuỗi New_Bornnày có trong danh sách Enum của tôi không

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

Tôi có thể sử dụng câu lệnh if cho ngay bây giờ, nhưng nếu danh sách Enum của tôi lớn hơn. Tôi muốn tìm một cách tốt hơn để làm điều đó. Tôi đang nghĩ đến việc sử dụng Linq, chỉ là không biết làm thế nào để làm điều đó.


2
Enum.IsDefinedkhông ổn?
leppie

Câu trả lời:


153

Bạn có thể dùng:

 Enum.IsDefined(typeof(Age), youragevariable)

IsDefined đòi hỏi Enum dụ để kiểm tra
Viacheslav Smityukh

9
Hãy nhớ rằng phân Enum.IsDefined()biệt chữ hoa chữ thường! Vì vậy, đó không phải là một "giải pháp phổ quát".
Cheshire Cat

6
Thông thường người ta khuyến cáo rằng không nên sử dụng IsDefined, vì Is sử dụng phản xạ, thực hiện một cuộc gọi tới IsDefined là một cuộc gọi rất tốn kém về mặt hiệu suất và CPU. Sử dụng TryParse để thay thế. (học từ pluralsight.com)
Weihui Guo

40

Bạn có thể sử dụng phương thức Enum.TryParse:

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

5
Đây là chỉ có sẵn như của .NET 4
Gary Richter

2
Vấn đề với điều này là nó sẽ trả về true nếu bạn cung cấp BẤT KỲ số nguyên nào (ý tôi là thay vì chuỗi "New_Born" của bạn).
Romain Vincent

10

Bạn có thể sử dụng phương thức TryParse trả về true nếu thành công:

Age age;

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

2

Tôi có một phương pháp mở rộng tiện dụng sử dụng TryParse, vì IsDefined phân biệt chữ hoa chữ thường.

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

1

Bạn nên sử dụng Enum.TryParse để đạt được mục tiêu của mình

Đây là một ví dụ:

[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

Tôi biết đây là một chuỗi cũ, nhưng đây là một cách tiếp cận hơi khác bằng cách sử dụng các thuộc tính trên Bảng kê và sau đó là lớp trợ giúp để tìm bảng liệt kê phù hợp.

Bằng cách này, bạn có thể có nhiều ánh xạ trên một bảng liệt kê.

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
}

Với lớp trợ giúp của tôi như thế này

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

}

sau đó bạn có thể làm một cái gì đó như

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

Và để hoàn thiện ở đây là thuộc tính:

 [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

Để phân tích độ tuổi:

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

Để xem nó có được định nghĩa hay không:

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

Tùy thuộc vào cách bạn định sử dụng Ageenum, cờ có thể không phù hợp. Như bạn có thể biết, [Flags]cho biết bạn muốn cho phép nhiều giá trị (như trong mặt nạ bit). IsDefinedsẽ trả về false Age.Toddler | Age.Preschoolvì nó có nhiều giá trị.


2
Nên sử dụng TryParse vì nó là đầu vào chưa được xác minh.
Phục vụ

1
MessageBox không thực sự có ý nghĩa trong môi trường web.
Phục vụ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.