Cách lấy giá trị enum theo chuỗi hoặc int


108

Làm cách nào để lấy giá trị enum nếu tôi có chuỗi enum hoặc giá trị int enum. ví dụ: Nếu tôi có một enum như sau:

public enum TestEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

và trong một số biến chuỗi tôi có giá trị "value1" như sau:

string str = "Value1" 

hoặc trong một số biến int tôi có giá trị 2 như

int a = 2;

làm thế nào tôi có thể lấy phiên bản của enum? Tôi muốn có một phương thức chung trong đó tôi có thể cung cấp enum và chuỗi đầu vào của tôi hoặc giá trị int để lấy phiên bản enum.


có thể có bản sao của Get enum int value by string

Câu trả lời:


210

Không, bạn không muốn một phương pháp chung chung. Điều này dễ dàng hơn nhiều:

MyEnum myEnum = (MyEnum)myInt;

MyEnum myEnum = (MyEnum)Enum.Parse(typeof(MyEnum), myString);

Tôi nghĩ rằng nó cũng sẽ nhanh hơn.


Đây thực sự là cách chính xác để làm điều này. Không có cách chung nào để phân tích cú pháp các loại vì cùng một lý do tại sao không có giao diện IParsable.
Johannes

1
@Johannes Ý bạn là gì? Có một cách chung chung, hãy tham khảo câu trả lời của tôi và những người khác nữa.
Sriram Sakthivel

1
@SriramSakthivel Vấn đề mà OP mô tả đã được giải quyết như KendallFrey đã chỉ ra. Không thể thực hiện phân tích cú pháp Chung - xem tại đây: Informit.com/blogs/blog.aspx?uk=Why-no-IParsably-interface . Bất kỳ giải pháp nào khác không có lợi thế so với giải pháp "tích hợp" của C #. Tối đa bạn có thể có một ICanSetFromString <T> nơi bạn tạo và khởi tạo một đối tượng về mặc định của nó (T) và trong một bước tiếp theo, truyền vào một chuỗi đại diện. Điều này gần với câu trả lời mà OP đã đưa ra - nhưng nó vô nghĩa vì thông thường đây là một vấn đề thiết kế và một điểm lớn hơn trong thiết kế hệ thống đã bị bỏ qua.
Johannes

Câu trả lời này hoạt động rất tốt, đặc biệt là với nhiều ví dụ về cách sử dụng int và string. Cảm ơn bạn.
Termato

1
Tôi nghĩ điều này đã hoạt động ngay bây giờ, nó ngắn gọn hơn một chút: Enum.Parse <MyEnum> (myString);
Phil B

32

Có rất nhiều cách để làm điều này, nhưng nếu bạn muốn có một ví dụ đơn giản, cách này sẽ làm được. Nó chỉ cần được tăng cường mã hóa phòng thủ cần thiết để kiểm tra độ an toàn của kiểu và phân tích cú pháp không hợp lệ, v.v.

    /// <summary>
    /// Extension method to return an enum value of type T for the given string.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static T ToEnum<T>(this string value)
    {
        return (T) Enum.Parse(typeof(T), value, true);
    }

    /// <summary>
    /// Extension method to return an enum value of type T for the given int.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static T ToEnum<T>(this int value)
    {
        var name = Enum.GetName(typeof(T), value);
        return name.ToEnum<T>();
    }

17

Có thể đơn giản hơn nhiều nếu bạn sử dụng TryParsehoặc ParseToObjectcác phương pháp.

public static class EnumHelper
{
    public static  T GetEnumValue<T>(string str) where T : struct, IConvertible
    {
        Type enumType = typeof(T);
        if (!enumType.IsEnum)
        {
            throw new Exception("T must be an Enumeration type.");
        }
        T val;
        return Enum.TryParse<T>(str, true, out val) ? val : default(T);
    }

    public static T GetEnumValue<T>(int intValue) where T : struct, IConvertible
    {
        Type enumType = typeof(T);
        if (!enumType.IsEnum)
        {
            throw new Exception("T must be an Enumeration type.");
        }

        return (T)Enum.ToObject(enumType, intValue);
    }
}

Như đã lưu ý bởi @chrfin trong nhận xét, bạn có thể biến nó thành một phương thức mở rộng rất dễ dàng chỉ bằng cách thêm vào thistrước loại tham số có thể hữu ích.


2
Bây giờ cũng thêm một thisvào tham số và tạo EnumHelpertĩnh và bạn cũng có thể sử dụng chúng làm phần mở rộng (xem câu trả lời của tôi, nhưng bạn có mã tốt hơn / hoàn chỉnh cho phần còn lại) ...
Christoph Fink

@chrfin Ý tưởng hay, nhưng tôi không thích nó vì nó sẽ xuất hiện trong intellisense, nơi nó không được yêu cầu khi chúng ta có không gian tên trong phạm vi. Tôi đoán nó sẽ rất khó chịu.
Sriram Sakthivel

1
@chrfin Cảm ơn bạn đã nhận xét, thêm vào như một ghi chú trong câu trả lời của tôi.
Sriram Sakthivel

5

Sau đây là phương thức trong C # để nhận giá trị enum theo chuỗi

///
/// Method to get enumeration value from string value.
///
///
///

public T GetEnumValue<T>(string str) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new Exception("T must be an Enumeration type.");
    }
    T val = ((T[])Enum.GetValues(typeof(T)))[0];
    if (!string.IsNullOrEmpty(str))
    {
        foreach (T enumValue in (T[])Enum.GetValues(typeof(T)))
        {
            if (enumValue.ToString().ToUpper().Equals(str.ToUpper()))
            {
                val = enumValue;
                break;
            }
        }
    }

    return val;
}

Sau đây là phương thức trong C # để lấy giá trị enum bởi int.

///
/// Method to get enumeration value from int value.
///
///
///

public T GetEnumValue<T>(int intValue) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new Exception("T must be an Enumeration type.");
    }
    T val = ((T[])Enum.GetValues(typeof(T)))[0];

    foreach (T enumValue in (T[])Enum.GetValues(typeof(T)))
    {
        if (Convert.ToInt32(enumValue).Equals(intValue))
        {
            val = enumValue;
            break;
        }             
    }
    return val;
}

Nếu tôi có một enum như sau:

public enum TestEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

thì tôi có thể sử dụng các phương pháp trên như

TestEnum reqValue = GetEnumValue<TestEnum>("Value1");  // Output: Value1
TestEnum reqValue2 = GetEnumValue<TestEnum>(2);        // OutPut: Value2

Hy vọng điều này sẽ giúp ích.


4
Bạn cũng có thể vui lòng cung cấp thông tin tham khảo về nơi bạn lấy cái này?
JonH

Để biên dịch điều này, tôi phải sửa đổi dòng đầu tiên thành public T GetEnumValue <T> (int intValue) trong đó T: struct, IConvertible Cũng hãy cẩn thận với một dấu '}' bổ sung ở cuối
Avi

3

Tôi nghĩ rằng bạn đã quên định nghĩa loại chung:

public T GetEnumValue<T>(int intValue) where T : struct, IConvertible // <T> added

và bạn có thể cải thiện nó để thuận tiện nhất như:

public static T ToEnum<T>(this string enumValue) : where T : struct, IConvertible
{
    return (T)Enum.Parse(typeof(T), enumValue);
}

thì bạn có thể làm:

TestEnum reqValue = "Value1".ToEnum<TestEnum>();

2

Hãy thử một cái gì đó như thế này

  public static TestEnum GetMyEnum(this string title)
        {    
            EnumBookType st;
            Enum.TryParse(title, out st);
            return st;          
         }

Vì vậy, bạn có thể làm

TestEnum en = "Value1".GetMyEnum();

2

Từ cơ sở dữ liệu SQL lấy enum như:

SqlDataReader dr = selectCmd.ExecuteReader();
while (dr.Read()) {
   EnumType et = (EnumType)Enum.Parse(typeof(EnumType), dr.GetString(0));
   ....         
}

2

Đơn giản chỉ cần thử cái này

Đó là một cách khác

public enum CaseOriginCode
{
    Web = 0,
    Email = 1,
    Telefoon = 2
}

public void setCaseOriginCode(string CaseOriginCode)
{
    int caseOriginCode = (int)(CaseOriginCode)Enum.Parse(typeof(CaseOriginCode), CaseOriginCode);
}

0

Đây là một ví dụ để lấy chuỗi / giá trị

    public enum Suit
    {
        Spades = 0x10,
        Hearts = 0x11,
        Clubs = 0x12,
        Diamonds = 0x13
    }

    private void print_suit()
    {
        foreach (var _suit in Enum.GetValues(typeof(Suit)))
        {
            int suitValue = (byte)(Suit)Enum.Parse(typeof(Suit), _suit.ToString());
            MessageBox.Show(_suit.ToString() + " value is 0x" + suitValue.ToString("X2"));
        }
    }

    Result of Message Boxes
    Spade value is 0x10
    Hearts value is 0x11
    Clubs value is 0x12
    Diamonds value is 0x13

0

Bạn có thể sử dụng phương pháp sau để làm điều đó:

public static Output GetEnumItem<Output, Input>(Input input)
    {
        //Output type checking...
        if (typeof(Output).BaseType != typeof(Enum))
            throw new Exception("Exception message...");

        //Input type checking: string type
        if (typeof(Input) == typeof(string))
            return (Output)Enum.Parse(typeof(Output), (dynamic)input);

        //Input type checking: Integer type
        if (typeof(Input) == typeof(Int16) ||
            typeof(Input) == typeof(Int32) ||
            typeof(Input) == typeof(Int64))

            return (Output)(dynamic)input;

        throw new Exception("Exception message...");
    }

Lưu ý: phương pháp này chỉ là mẫu và bạn có thể cải thiện nó.

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.