Soru Bir numarayı nasıl numaralandırırım?


Nasıl numaralandırırsınız? enum C # içinde?

Örneğin. Aşağıdaki kod derlenmiyor:

public enum Suit 
{
    Spades,
    Hearts,
    Clubs,
    Diamonds
}

public void EnumerateAllSuitsDemoMethod() 
{
    foreach (Suit suit in Suit) 
    {
        DoSomething(suit);
    }
}

Ve aşağıdaki derleme zamanı hatası verir:

'Suit' bir 'tip' ama 'değişken' gibi kullanılır

Üzerinde başarısız Suit anahtar kelime, ikincisi.


3119
2017-09-19 20:34


Menşei


Ayrıca bakınız ... stackoverflow.com/questions/972307/... - SteveC
@ChaseMedallion Bağlantınız ölü gibi görünüyor. - Clearer
Kontrol etmek isteyebilirsiniz C # enums in ins ve çıkışları, bunun yanı sıra diğer yararlı enum çerezleri de tartışıyor - ChaseMedallion
@Clearer teşekkürler Bağlantıyı güncelledim. - ChaseMedallion


Cevaplar:


foreach (Suit suit in (Suit[]) Enum.GetValues(typeof(Suit)))
{
}

3896
2017-09-19 20:37



Numaratör listesinde yinelenen değerler varsa, bu işe yaramaz. - Jessy
Silverlight kütüphanesi içermediğinden, maalesef gümüş madalyada çalışmayacağımı belirtmek istiyorum. enum.GetValues. Bu durumda yansımayı kullanmalısın. - Giacomo Tagliabue
@Jessy this yapar gibi yinelenen durumlar durumunda çalışmak enum E {A = 0, B = 0}. Enum.GetValues aynı oldukları halde iki değer döndürülür. E.A == E.B doğrudur, bu yüzden ayrım yoktur. Eğer bireysel isimleri istiyorsanız, o zaman aramalısınız. Enum.GetNames. - nawfal
Sonra numaranızda çiftler / eş anlamlılar varsa ve diğer davranışı istiyorsanız, Linq'leri kullanabilirsiniz. Distinct uzantısı (.NET 3.5'ten beri) foreach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }. - Jeppe Stig Nielsen
Kullanmaya çalışırken hata yaptım var türü için. Derleyici değişkeni bir Object enum yerine. Enum türünü açıkça listeleyin. - jpmc26


Bana, değerler yerine, her bir enumun isimlerini yazdırmak istediğiniz gibi görünüyor. Bu durumda Enum.GetNames() doğru yaklaşım gibi görünüyor.

public enum Suits
{
    Spades,
    Hearts,
    Clubs,
    Diamonds,
    NumSuits
}

public void PrintAllSuits()
{
    foreach (string name in Enum.GetNames(typeof(Suits)))
    {
        System.Console.WriteLine(name);
    }
}

Bu arada, değeri artırmak bir enum'un değerlerini saymak için iyi bir yol değildir. Bunu yerine yapmalısın.

Kullanmak istiyorum Enum.GetValues(typeof(Suit)) yerine.

public enum Suits
{
    Spades,
    Hearts,
    Clubs,
    Diamonds,
    NumSuits
}

public void PrintAllSuits()
{
    foreach (var suit in Enum.GetValues(typeof(Suits)))
    {
        System.Console.WriteLine(suit.ToString());
    }
}

562
2017-09-19 20:39





Kolay enum kullanımı için bazı uzantılar yaptım, belki biri kullanabilir ...

public static class EnumExtensions
{
    /// <summary>
    /// Gets all items for an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>(this Enum value)
    {
        foreach (object item in Enum.GetValues(typeof(T)))
        {
            yield return (T)item;
        }
    }

    /// <summary>
    /// Gets all items for an enum type.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>() where T : struct
    {
        foreach (object item in Enum.GetValues(typeof(T)))
        {
            yield return (T)item;
        }
    }

    /// <summary>
    /// Gets all combined items from an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <example>
    /// Displays ValueA and ValueB.
    /// <code>
    /// EnumExample dummy = EnumExample.Combi;
    /// foreach (var item in dummy.GetAllSelectedItems<EnumExample>())
    /// {
    ///    Console.WriteLine(item);
    /// }
    /// </code>
    /// </example>
    public static IEnumerable<T> GetAllSelectedItems<T>(this Enum value)
    {
        int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);

        foreach (object item in Enum.GetValues(typeof(T)))
        {
            int itemAsInt = Convert.ToInt32(item, CultureInfo.InvariantCulture);

            if (itemAsInt == (valueAsInt & itemAsInt))
            {
                yield return (T)item;
            }
        }
    }

    /// <summary>
    /// Determines whether the enum value contains a specific value.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <param name="request">The request.</param>
    /// <returns>
    ///     <c>true</c> if value contains the specified value; otherwise, <c>false</c>.
    /// </returns>
    /// <example>
    /// <code>
    /// EnumExample dummy = EnumExample.Combi;
    /// if (dummy.Contains<EnumExample>(EnumExample.ValueA))
    /// {
    ///     Console.WriteLine("dummy contains EnumExample.ValueA");
    /// }
    /// </code>
    /// </example>
    public static bool Contains<T>(this Enum value, T request)
    {
        int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);
        int requestAsInt = Convert.ToInt32(request, CultureInfo.InvariantCulture);

        if (requestAsInt == (valueAsInt & requestAsInt))
        {
            return true;
        }

        return false;
    }
}

Enum kendisi ile dekore edilmelidir FlagsAttribute

[Flags]
public enum EnumExample
{
    ValueA = 1,
    ValueB = 2,
    ValueC = 4,
    ValueD = 8,
    Combi = ValueA | ValueB
}

287
2018-06-03 12:03



İlk uzatma yöntemi için bir astar; Artık tembel değil. Enum.GetValues ​​döndür (typeof (T)) <T> (); - Leyu
Alternatif olarak OfType da kullanabilirsiniz: Enum.GetValues ​​(typeof (T)) OfType <T> (). GetValues ​​<T> () 'ın genel bir sürümü olmadığı için çok kötü, daha da kaygan olacaktır. - jpierson
Belki birisi bu uzantıları nasıl kullanabileceğini gösterebilir? Derleyici, EnumExample enum'da uzantı yöntemleri göstermiyor. - Tomas
Bu işlevleri nasıl kullanacağına örnek ekleyebilir misiniz? - Ashwini Verma
Yeniden kullanılabilir kod için +1: örnekler - bu uzantı yöntemlerini bir kitaplığa kaydedin ve [Flags] public enum mytypes {name1, name2}; Liste <string> myTypeNames = mytypes.GetAllItems (); - Krishna


.NET çerçevesinin bazı sürümleri desteklemiyor Enum.GetValues. İşte iyi bir geçici çözüm Fikirler 2.0: Kompakt Çerçevede Enum.GetValues:

public List<Enum> GetValues(Enum enumeration)
{
   List<Enum> enumerations = new List<Enum>();
   foreach (FieldInfo fieldInfo in enumeration.GetType().GetFields(
         BindingFlags.Static | BindingFlags.Public))
   {
      enumerations.Add((Enum)fieldInfo.GetValue(enumeration));
   }
   return enumerations;
}

İçerdiği herhangi bir kodla olduğu gibi yansımaSadece bir kez çalıştığından ve sonuçların önbelleğe alındığından emin olmak için adımlar atmalısınız.


147
2017-09-03 18:48



Neden bir liste oluşturmak yerine getiri anahtar kelimesini kullanmıyorsunuz? - Eric Mickelsen
veya daha kısa: return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>(); - nawfal
@nawfal: Linq yok. Net CF 2.0. - Gabriel GM
@Ekevoo Bu enum değerleri MVC'de bir DropDownList'e nasıl bağlanır? - Clint Eastwood


Bunun diğer önerilerden daha verimli olduğunu düşünüyorum çünkü GetValues() Bir döngü olduğunda her zaman çağrılmaz. Ayrıca daha özlüdür. Ve bir çalışma zamanı özel durumu değil, bir derleme zamanı hatası alıyorsunuz Suit bir değil enum.

EnumLoop<Suit>.ForEach((suit) => {
    DoSomethingWith(suit);
});

EnumLoop bu tamamen jenerik tanımı var:

class EnumLoop<Key> where Key : struct, IConvertible {
    static readonly Key[] arr = (Key[])Enum.GetValues(typeof(Key));
    static internal void ForEach(Action<Key> act) {
        for (int i = 0; i < arr.Length; i++) {
            act(arr[i]);
        }
    }
}

85
2018-02-02 13:36



Bunun gibi jenerikler kullanmaya dikkat edin. Kullanmaya çalışırsanız EnumLoop bir tür olmayan bir türle, iyi derler, ancak çalışma zamanında bir istisna atar. - svick
Teşekkür ederim svick. Çalışma zamanı istisnaları, aslında bu sayfadaki diğer yanıtlarla birlikte gerçekleşecektir ... bunun dışında, bunun yerine "Anahtar: struct, IConvertible" ifadesini ekledim, böylece çoğu durumda derleme zamanı hatası aldınız. - James
Hayır, GetValues ​​() foreach'da sadece bir kez çağrılır. - Alex Blokha
James, sınıfınızı vazgeçiririm çünkü zekice yazmak güzeldir, ancak üretim kodunda pek çok insanın bakımını yapması ve güncellenmesi akıllıcadır. Eğer büyük bir tasarruf sağlarsa veya çok kullanılacaksa - tasarruflar büyüktür ve insanlar buna aşina olacaktır - buna değer, ama çoğu durumda kodu okumaya ve güncellemeye çalışan kişileri yavaşlatır ve olası Gelecekte kaynak hataları. Daha az kod daha iyidir :) daha az karmaşıklık daha iyidir. - Grant M
@James Bu enum değerlerini MVC'de bir DropDownList'e bağlamak için bir örnek verebilir misiniz? - Clint Eastwood


Neden kimse kullanmıyor Cast<T>?

var suits = Enum.GetValues(typeof(Suit)).Cast<Suit>();

İşte gidiyorsun IEnumerable<Suit>.


82
2018-03-17 04:15



Eğer LINQ kullanabiliyorsanız oldukça havalıdır ... - MemphiZ
Bu aynı zamanda from fıkra ve foreach başlık declarator. - Aluan Haddad


Alamayacaksın Enum.GetValues() Silverlight'ta.

Einar Ingebrigtsen tarafından özgün blog yazısı:

public class EnumHelper
{
    public static T[] GetValues<T>()
    {
        Type enumType = typeof(T);

        if (!enumType.IsEnum)
        {
            throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
        }

        List<T> values = new List<T>();

        var fields = from field in enumType.GetFields()
                     where field.IsLiteral
                     select field;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(enumType);
            values.Add((T)value);
        }

        return values.ToArray();
    }

    public static object[] GetValues(Type enumType)
    {
        if (!enumType.IsEnum)
        {
            throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
        }

        List<object> values = new List<object>();

        var fields = from field in enumType.GetFields()
                     where field.IsLiteral
                     select field;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(enumType);
            values.Add(value);
        }

        return values.ToArray();
    }
}

68
2017-11-17 01:29



Güzel bir çözüm, ama bazı refactoring daha iyi olacak! :) - nawfal
@AubreyTaylor Bu enum değerlerini MVC'de bir DropDownList'e bağlamak için bir örnek verebilir misiniz? - Clint Eastwood
.NET framework 4.0 & silverlight enum.getvalues ​​çalışmasını kullanıyorum, kullandığım kod ---> enum.GetValues ​​(typeof (enum)) - Ananda
C # 7.3 ile başlayarak (Visual Studio 2017 ≥ v15.7), birini kullanabilirsiniz where T: Enum - Yahoo Serious


Kompakt çerçevede (3.5) çalışan ve tip kontrolünü destekleyen çözümümü eklemek için derleme zamanında:

public static List<T> GetEnumValues<T>() where T : new() {
    T valueType = new T();
    return typeof(T).GetFields()
        .Select(fieldInfo => (T)fieldInfo.GetValue(valueType))
        .Distinct()
        .ToList();
}

public static List<String> GetEnumNames<T>() {
    return typeof (T).GetFields()
        .Select(info => info.Name)
        .Distinct()
        .ToList();
}

- Eğer kimsenin nasıl kurtulacağını bilen varsa T valueType = new T()Bir çözüm görmekten mutluluk duyarım.

Bir çağrı şöyle görünecekti:

List<MyEnum> result = Utils.GetEnumValues<MyEnum>();

50
2017-07-07 13:37



ne kullanıyorsun T valueType = default(T)? - Oliver
Harika, bu anahtar kelimeyi bile bilmiyordum. Yeni bir şeyler öğrenmek her zaman güzel. Teşekkür ederim! Her zaman aynı nesneye bir başvuru döndürüyor mu, yoksa varsayılan ifade çağrıldığında her defasında yeni bir örnek oluşturuyor mu? Şimdiye kadar bu konuda net bir şey bulamadım, ama her seferinde yeni bir örnek yaratırsa, aradığım amacı yenerim (tek liner ^^ sahip olmak). - Mallox
.GetValue (yeni T ())? - Jason Miesionczek
Bu, numaralandırmadaki her yineleme için yeni bir örnek oluşturmaz mı? - Mallox
-1 için "derleme zamanında tür denetimini destekler:". Ne tür kontrol? Bu herhangi bir işe yarayacak new()  T. Ayrıca, ihtiyacınız yok new T()sadece, sadece statik alanları seçebilir ve .GetValue(null). Aubrey'nin cevabına bak. - nawfal


Sanırım kullanabilirsin

Enum.GetNames(Suit)

44
2017-09-19 20:37



Enum.GetValues ​​(uygun) - Ian Boyd


public void PrintAllSuits()
{
    foreach(string suit in Enum.GetNames(typeof(Suits)))
    {
        Console.WriteLine(suit);
    }
}

42
2017-09-19 21:05



Bu bir dizeyi numaralandırır, bu şeyleri bir numaralandırma numarasına dönüştürmeyi unutmayın, böylece numaralandırma numaralandırılabilir. - Ian Boyd
Düzenlemelerinizden gerçekten de enumlar üzerinde çalışmak istediğinizi görüyorum, yukarıdaki kod orijinal yayınınızı ele aldı. - Joshua Drake