Dize veya int ile enum değeri nasıl alınır


108

Enum dizesine veya enum int değerine sahipsem enum değerini nasıl alabilirim. Örneğin: Aşağıdaki gibi bir numaram varsa:

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

ve bazı dize değişkenlerinde aşağıdaki gibi "değer1" değerine sahibim:

string str = "Value1" 

veya bazı int değişkenlerinde 2 değerine sahibim

int a = 2;

enum örneğini nasıl alabilirim? Numaralandırma örneğini almak için numaralandırmayı ve girdi dizemi veya int değerimi sağlayabileceğim genel bir yöntem istiyorum.


Yanıtlar:


211

Hayır, genel bir yöntem istemezsiniz. Bu çok daha kolay:

MyEnum myEnum = (MyEnum)myInt;

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

Ben de daha hızlı olacağını düşünüyorum.


Aslında bunu yapmanın doğru yolu budur. IParable arabiriminin olmamasının nedeniyle aynı nedenle türleri ayrıştırmanın genel bir yolu yoktur.
Johannes

1
@Johannes Bununla ne demek istiyorsun? Genel bir yol var, cevabıma ve diğerlerine de bakın.
Sriram Sakthivel

1
@SriramSakthivel OP'nin tanımladığı sorun KendallFrey'in gösterdiği gibi çözüldü. Genel Ayrıştırma yapılamaz - buraya bakın: informit.com/blogs/blog.aspx?uk=Why-no-IParseable-interface . Başka herhangi bir çözümün, C # 'ın "yerleşik" çözümüne kıyasla hiçbir avantajı yoktur. Sahip olabileceğiniz maksimum değer, bir nesneyi oluşturup varsayılanına (T) başlattığınız ve bir sonraki adımda temsili bir dizede geçirdiğiniz bir ICanSetFromString <T> değeridir. Bu, OP'nin verdiği cevaba yakındır - ancak anlamsızdır çünkü genellikle bu bir tasarım sorunudur ve sistem tasarımında daha büyük bir nokta gözden kaçmıştır.
Johannes

Bu cevap, özellikle birden çok int ve string kullanım örneğinde çok işe yaradı. Teşekkür ederim.
Termato

1
Sanırım şimdi işe yarıyor, biraz daha özlü: Enum.Parse <MyEnum> (myString);
Phil B

32

Bunu yapmanın birçok yolu vardır, ancak basit bir örnek istiyorsanız, bu yeterli olacaktır. Sadece tür güvenliğini ve geçersiz ayrıştırmayı vb. Kontrol etmek için gerekli savunma kodlamasıyla geliştirilmesi gerekiyor.

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

TryParseVeya Parseve ToObjectyöntemlerini kullanırsanız çok daha basit olabilir .

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 tarafından yorumlarda belirtildiği gibi, thiskullanışlı olabilecek parametre türünden önce ekleyerek bunu çok kolay bir şekilde bir genişletme yöntemi haline getirebilirsiniz.


2
Şimdi de thisparametreye bir ekleyin ve EnumHelperstatik yapın ve bunları uzantı olarak da kullanabilirsiniz (cevabıma bakın, ancak geri kalanı için daha iyi / eksiksiz bir kodunuz var) ...
Christoph Fink

@chrfin İyi fikir, ancak kapsamda ad alanlarımız olduğunda gerekli olmayan intellisense'de patlama olacağı için tercih etmiyorum. Sanırım can sıkıcı olacak.
Sriram Sakthivel

1
@chrfin Cevabıma not olarak eklenen yorum için teşekkürler.
Sriram Sakthivel

5

Aşağıda dizeye göre enum değerini almak için C # yöntemi verilmiştir

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

Enum değerini int ile elde etmek için C # 'da yöntem aşağıdadır.

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

Aşağıdaki gibi bir numaram varsa:

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

daha sonra yukarıdaki yöntemleri şu şekilde kullanabilirim:

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

Umarım bu yardımcı olur.


4
Ayrıca bunu nereden aldığınıza dair referans verebilir misiniz?
JonH

Bunun derlenmesi için, ilk satırı halka açık T GetEnumValue <T> (intValue) olarak değiştirmem gerekiyordu, burada T: struct, IConvertible Ayrıca sonda fazladan bir '}' dikkat edin
Avi

3

Sanırım genel tür tanımını unuttunuz:

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

ve bunu en uygun şekilde iyileştirebilirsiniz, örneğin:

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

o zaman yapabilirsin:

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

2

Bunun gibi bir şey dene

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

Yani yapabilirsin

TestEnum en = "Value1".GetMyEnum();

2

SQL veritabanından aşağıdaki gibi numaralandırma alın:

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

2

Sadece bunu dene

Bu başka bir yol

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

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

0

İşte dize / değer almak için bir örnek

    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

Bunu yapmak için aşağıdaki yöntemi kullanabilirsiniz:

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

Not: Bu yöntem yalnızca bir örnektir ve onu geliştirebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.