วิธีรับค่า enum ด้วยสตริงหรือ int


110

ฉันจะรับค่า enum ได้อย่างไรถ้าฉันมีสตริง enum หรือค่า int enum เช่น: ถ้าฉันมี enum ดังนี้:

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

และในตัวแปรสตริงฉันมีค่า "value1" ดังนี้:

string str = "Value1" 

หรือในตัวแปร int บางตัวฉันมีค่า 2 เช่น

int a = 2;

ฉันจะรับตัวอย่างของ enum ได้อย่างไร ฉันต้องการวิธีการทั่วไปที่ฉันสามารถระบุ enum และสตริงอินพุตหรือค่า int ของฉันเพื่อรับอินสแตนซ์ enum


อาจซ้ำกันได้ของGet enum int value ตามสตริง

คำตอบ:


219

ไม่คุณไม่ต้องการวิธีการทั่วไป ง่ายกว่ามาก:

MyEnum myEnum = (MyEnum)myInt;

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

ฉันคิดว่ามันจะเร็วขึ้นด้วย


นี่เป็นวิธีที่ถูกต้องในการทำเช่นนี้ ไม่มีวิธีทั่วไปในการแยกวิเคราะห์ประเภทด้วยเหตุผลเดียวกับที่ไม่มีอินเทอร์เฟซ IParsable
Johannes

1
@ โจฮันเนสคุณหมายถึงอะไร? มีวิธีทั่วไปอ้างอิงคำตอบของฉันและอื่น ๆ ด้วย
Sriram Sakthivel

1
@SriramSakthivel ปัญหาที่ OP อธิบายได้รับการแก้ไขเหมือนที่ KendallFrey แสดงให้เห็น ทั่วไปแยกไม่สามารถทำได้ - ดูที่นี่: informit.com/blogs/blog.aspx?uk=Why-no-IParseable-interface โซลูชันอื่นใดไม่มีข้อได้เปรียบเมื่อเทียบกับโซลูชัน "ออนบอร์ด" ของ C # ค่าสูงสุดที่คุณสามารถมีได้คือ ICanSetFromString <T> ที่คุณสร้างและเริ่มต้นอ็อบเจ็กต์เป็นค่าเริ่มต้น (T) และในขั้นตอนถัดไปจะส่งผ่านในสตริงตัวแทน สิ่งนี้ใกล้เคียงกับคำตอบที่ OP ให้ - แต่ก็ไม่มีจุดหมายเพราะโดยปกติแล้วนี่เป็นปัญหาในการออกแบบและพลาดจุดที่ใหญ่กว่าในการออกแบบระบบ
Johannes

คำตอบนี้ใช้ได้ดีมากโดยเฉพาะอย่างยิ่งกับตัวอย่างต่างๆของการใช้งาน int และสตริง ขอขอบคุณ.
Termato

1
ฉันคิดว่าตอนนี้ใช้งานได้แล้วมันกระชับขึ้นเล็กน้อย: Enum.Parse <MyEnum> (myString);
Phil B

32

มีหลายวิธีในการทำเช่นนี้ แต่ถ้าคุณต้องการตัวอย่างง่ายๆก็จะทำได้ เพียงแค่ต้องได้รับการปรับปรุงด้วยการเข้ารหัสป้องกันที่จำเป็นเพื่อตรวจสอบความปลอดภัยของประเภทและการแยกวิเคราะห์ที่ไม่ถูกต้อง ฯลฯ

    /// <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

อาจจะง่ายกว่ามากหากคุณใช้TryParseหรือParseและToObjectวิธีการ

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

ตามที่ระบุไว้โดย @chrfin ในความคิดเห็นคุณสามารถทำให้เป็นวิธีการขยายได้อย่างง่ายดายเพียงแค่เพิ่มthisก่อนประเภทพารามิเตอร์ซึ่งสามารถใช้งานได้สะดวก


2
ตอนนี้เพิ่มthisพารามิเตอร์และสร้างEnumHelperแบบคงที่และคุณสามารถใช้เป็นส่วนขยายได้เช่นกัน (ดูคำตอบของฉัน แต่คุณมีรหัสที่ดีกว่า / สมบูรณ์สำหรับส่วนที่เหลือ) ...
Christoph Fink

@chrfin เป็นความคิดที่ดี แต่ฉันไม่ชอบเพราะมันจะโผล่ขึ้นมาใน Intellisense ซึ่งไม่จำเป็นเมื่อเรามีเนมสเปซในขอบเขต มันจะน่ารำคาญฉันเดา
Sriram Sakthivel

1
@chrfin ขอบคุณสำหรับความคิดเห็นเพิ่มเป็นหมายเหตุในคำตอบของฉัน
Sriram Sakthivel

5

ต่อไปนี้เป็นวิธีการใน C # เพื่อรับค่า enum ด้วยสตริง

///
/// 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;
}

ต่อไปนี้เป็นวิธีการใน C # เพื่อรับค่า enum โดย 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;
}

ถ้าฉันมี enum ดังนี้:

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

จากนั้นฉันสามารถใช้วิธีการข้างต้นเป็น

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

หวังว่านี่จะช่วยได้


4
คุณสามารถระบุแหล่งที่มาของสิ่งนี้ได้หรือไม่?
JonH

สำหรับสิ่งนี้ในการคอมไพล์ฉันต้องแก้ไขบรรทัดแรกเป็น T GetEnumValue <T> สาธารณะ (int intValue) โดยที่ T: struct, IConvertible โปรดระวังส่วนเกิน "}" ในตอนท้าย
Avi

3

ฉันคิดว่าคุณลืมคำจำกัดความประเภททั่วไป:

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

และคุณสามารถปรับปรุงให้น่าใช้ที่สุดเช่น:

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

จากนั้นคุณสามารถทำได้:

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

2

ลองอะไรแบบนี้

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

ดังนั้นคุณสามารถทำได้

TestEnum en = "Value1".GetMyEnum();

2

จากฐานข้อมูล SQL รับ enum เช่น:

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

2

ลองทำตามนี้

มันเป็นอีกวิธีหนึ่ง

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

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

0

นี่คือตัวอย่างเพื่อรับสตริง / ค่า

    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

คุณสามารถใช้วิธีการต่อไปนี้เพื่อทำสิ่งนั้น:

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...");
    }

หมายเหตุ: วิธีนี้เป็นเพียงตัวอย่างและคุณสามารถปรับปรุงได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.