it-swarm-eu.dev

Jak mohu vypsat výčet v jazyce C #?

Jak můžete výčet enum v C #?

Např. následující kód není zkompilován:

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

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

A dává následující chybu při kompilaci:

'Suit' je 'typ', ale používá se jako 'proměnná'

To se nezdaří v klíčovém slově Suit, druhém.

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

Poznámka : Obsazení do (Suit[]) není nezbytně nutné, ale dělá kód 0,5 ns rychlejším.

4232
jop

Vypadá to, že opravdu chcete vytisknout jména jednotlivých výčtů, nikoli hodnoty. V takovém případě se zdá být Enum.GetNames() správným přístupem.

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

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

Mimochodem, zvýšení hodnoty není dobrý způsob, jak vyčíslit hodnoty výčtu. Měli byste to udělat místo toho.

Místo toho bych použil Enum.GetValues(typeof(Suit)).

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

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

Udělal jsem několik rozšíření pro snadné použití enum, možná to někdo může použít ...

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

Samotný výčet musí být zdoben příznaky PříznakyAttribute

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

Některé verze rozhraní .NET nepodporují Enum.GetValues. Zde je dobré řešení z Ideas 2.0: Enum.GetValues ​​v Compact Framework :

public Enum[] GetValues(Enum enumeration)
{
    FieldInfo[] fields = enumeration.GetType().GetFields(BindingFlags.Static | BindingFlags.Public);
    Enum[] enumerations = new Enum[fields.Length];

    for (var i = 0; i < fields.Length; i++)
        enumerations[i] = (Enum) fields[i].GetValue(enumeration);

    return enumerations;
}

Stejně jako u jiných kódů, které zahrnují reflexe , měli byste podniknout kroky, které zajistí, že budou spuštěny pouze jednou a výsledky budou ukládány do mezipaměti.

165
Ekevoo

Proč nikdo nepoužívá Cast<T>?

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

Tam jdete IEnumerable<Suit>.

97
sircodesalot

Myslím, že je to efektivnější než jiné návrhy, protože GetValues() není volána pokaždé, když máte smyčku. Je také stručnější. A pokud chyba Suit není enum, chyba při kompilaci není runtime výjimkou.

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

EnumLoop má tuto zcela obecnou definici:

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]);
        }
    }
}
90
James

V Silverlightu nedostanete Enum.GetValues().

Původní příspěvek blogu Einar Ingebrigtsen :

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

Stačí přidat mé řešení, které pracuje v kompaktním rámci (3.5) a podporuje kontrolu typu při kompilaci :

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

- Pokud někdo ví, jak se zbavit T valueType = new T(), rád bych viděl řešení.

Hovor by vypadal takto:

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

Myslím, že můžete použít

Enum.GetNames(Suit)
48
Tom Carr
public void PrintAllSuits()
{
    foreach(string suit in Enum.GetNames(typeof(Suits)))
    {
        Console.WriteLine(suit);
    }
}
46
Joshua Drake
foreach (Suit suit in Enum.GetValues(typeof(Suit))) { }

Slyšel jsem neurčité zvěsti, že je to hrozně pomalé. Někdo to ví? - Orion Edwards Oct 15 '08 v 1:31 7

Myslím, že ukládání do mezipaměti pole by to značně urychlilo. Vypadá to, že pokaždé dostanete nové pole (přes odraz). Spíše:

Array enums = Enum.GetValues(typeof(Suit));
foreach (Suit suitEnum in enums) 
{
    DoSomething(suitEnum);
}

To je alespoň trochu rychlejší, ja?

44
Limited Atonement

Tři způsoby:

1. Enum.GetValues(type) //since .NET 1.1, not in silverlight or compact framewok
2. type.GetEnumValues() //only on .NET 4 and above
3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) //works everywhere

Nejste si jisti, proč bylo GetEnumValues zavedeno na instanci typu, pro mě to není vůbec čitelné.


Mít pomocnou třídu, jako je Enum<T>, je to, co je pro mě nejčitelnější a nejpamátnější:

public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
    public static IEnumerable<T> GetValues()
    {
        return (T[])Enum.GetValues(typeof(T));
    }

    public static IEnumerable<string> GetNames()
    {
        return Enum.GetNames(typeof(T));
    }
}

Nyní voláte:

Enum<Suit>.GetValues();
//or
Enum.GetValues(typeof(Suit)); //pretty consistent style

Člověk může také použít určitý druh ukládání do mezipaměti, pokud záleží na výkonu, ale neočekávám, že to bude vůbec problém

public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
    //lazily loaded
    static T[] values;
    static string[] names;

    public static IEnumerable<T> GetValues()
    {
        return values ?? (values = (T[])Enum.GetValues(typeof(T)));
    }

    public static IEnumerable<string> GetNames()
    {
        return names ?? (names = Enum.GetNames(typeof(T)));
    }
}
25
nawfal

K čertu budu vrhat dva pence, jen kombinací nejlepších odpovědí, které jsem provedl dohromady, velmi jednoduchým rozšířením

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 T value) where T : Enum
    {
        return (T[])Enum.GetValues(typeof (T));
    }
}

Čisté jednoduché a @ Jeppe-Stig-Nielsen komentář rychle.

22
Darkside

Používám ToString (), pak rozdělit a analyzovat spit pole ve vlajkách.

[Flags]
public enum ABC {
   a = 1,
   b = 2,
   c = 4
};

public IEnumerable<ABC> Getselected (ABC flags)
{
   var values = flags.ToString().Split(',');
   var enums = values.Select(x => (ABC)Enum.Parse(typeof(ABC), x.Trim()));
   return enums;
}

ABC temp= ABC.a | ABC.b;
var list = getSelected (temp);
foreach (var item in list)
{
   Console.WriteLine(item.ToString() + " ID=" + (int)item);
}
21
Mickey Perlstein

Existují dva způsoby opakování proměnné Enum:

1. var values =  Enum.GetValues(typeof(myenum))
2. var values =  Enum.GetNames(typeof(myenum))

První vám dá hodnoty ve tvaru poleobject, a druhá vám poskytne hodnoty ve tvaru poleString.

Použijte jej ve smyčce foreach takto:

foreach(var value in values)
{
    //Do operations here
}
21
Kylo Ren

Potřebujete-li kontrolu rychlosti a typu při sestavení a době běhu, je tato pomocná metoda lepší než použití funkce LINQ k odevzdání každého prvku:

public static T[] GetEnumValues<T>() where T : struct, IComparable, IFormattable, IConvertible
{
    if (typeof(T).BaseType != typeof(Enum))
    {
        throw new ArgumentException(string.Format("{0} is not of type System.Enum", typeof(T)));
    }
    return Enum.GetValues(typeof(T)) as T[];
}

A můžete jej použít jako níže:

static readonly YourEnum[] _values = GetEnumValues<YourEnum>();

Samozřejmě se můžete vrátit IEnumerable<T>, ale tady vám nic nekupuje.

15
dmihailescu

Nemám názor, že je to lepší, nebo dokonce dobré, jen říkat další řešení.

Pokud se enum hodnoty pohybují přesně od 0 do n - 1, obecná alternativa:

public void EnumerateEnum<T>()
{
    int length = Enum.GetValues(typeof(T)).Length;
    for (var i = 0; i < length; i++)
    {
        var @enum = (T)(object)i;
    }
}

Pokud jsou hodnoty enum souvislé a můžete zadat první a poslední prvek enum, pak:

public void EnumerateEnum()
{
    for (var i = Suit.Spade; i <= Suit.Diamond; i++)
    {
        var @enum = i;
    }
}

ale to není striktně výčet, jen opakování. Druhá metoda je mnohem rychlejší než jakýkoli jiný přístup.

15
nawfal

zde je pracovní příklad vytváření volitelných možností pro DDL

var resman = ViewModelResources.TimeFrame.ResourceManager;

ViewBag.TimeFrames = from MapOverlayTimeFrames timeFrame 
      in Enum.GetValues(typeof(MapOverlayTimeFrames))
      select new SelectListItem
      {
         Value = timeFrame.ToString(),
         Text = resman.GetString(timeFrame.ToString()) ?? timeFrame.ToString()
      };
12
jhilden
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
}

(Aktuální přijatá odpověď má obsazení, které si nemyslím, že je potřeba (i když se možná mýlím).)

10
matt burns

Tato otázka se zobrazí v kapitole 10 části „ C # Krok za krokem 2013

Autor používá dvojitou smyčku pro opakování pomocí dvojice Enumerátorů (pro vytvoření plné sady karet):

class Pack
{
    public const int NumSuits = 4;
    public const int CardsPerSuit = 13;
    private PlayingCard[,] cardPack;

    public Pack()
    {
        this.cardPack = new PlayingCard[NumSuits, CardsPerSuit];
        for (Suit suit = Suit.Clubs; suit <= Suit.Spades; suit++)
        {
            for (Value value = Value.Two; value <= Value.Ace; value++)
            {
                cardPack[(int)suit, (int)value] = new PlayingCard(suit, value);
            }
        }
    }
}

V tomto případě jsou Suit a Value oba výčty:

enum Suit { Clubs, Diamonds, Hearts, Spades }
enum Value { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace}

a PlayingCard je objekt karty s definovaným Suit a Value:

class PlayingCard
{
    private readonly Suit suit;
    private readonly Value value;

    public PlayingCard(Suit s, Value v)
    {
        this.suit = s;
        this.value = v;
    }
}
9
Ross Gatih

Vím, že je to trochu chaotický, ale pokud jste fanouškem jednořadých linek, tady je jeden:

((Suit[])Enum.GetValues(typeof(Suit))).ToList().ForEach(i => DoSomething(i));
8
anar khalilov

Co když víte, že typ bude enum, ale nevíte, jaký je přesný typ v době kompilace?

public class EnumHelper
{
    public static IEnumerable<T> GetValues<T>()
    {
        return Enum.GetValues(typeof(T)).Cast<T>();
    }

    public static IEnumerable getListOfEnum(Type type)
    {
        MethodInfo getValuesMethod = typeof(EnumHelper).GetMethod("GetValues").MakeGenericMethod(type);
        return (IEnumerable)getValuesMethod.Invoke(null, null);
    }
}

Metoda getListOfEnum používá reflexi, aby brala libovolný typ enum a vrací IEnumerable všech hodnot enum.

Používání:

Type myType = someEnumValue.GetType();

IEnumerable resultEnumerable = getListOfEnum(myType);

foreach (var item in resultEnumerable)
{
    Console.WriteLine(String.Format("Item: {0} Value: {1}",item.ToString(),(int)item));
}
7
Slappywag

Jednoduchý a obecný způsob, jak převést výčet na něco, s čím můžete komunikovat:

public static Dictionary<int, string> ToList<T>() where T : struct
{
   return ((IEnumerable<T>)Enum
       .GetValues(typeof(T)))
       .ToDictionary(
           item => Convert.ToInt32(item),
           item => item.ToString());
}

A pak:

var enums = EnumHelper.ToList<MyEnum>();
7
Gabriel

Přidejte metodu public static IEnumerable<T> GetValues<T>() do vaší třídy, jako

public static IEnumerable<T> GetValues<T>()
{
    return Enum.GetValues(typeof(T)).Cast<T>();
}

zavolat a projít svůj výčet, nyní jej můžete iterovat pomocí foreach

 public static void EnumerateAllSuitsDemoMethod()
 {
     // custom method
     var foos = GetValues<Suit>(); 
     foreach (var foo in foos)
     {
         // Do something
     }
 }
4
MUT

enum typy se nazývají "typy výčtů" ne proto, že se jedná o kontejnery, které "enumerují" hodnoty (které nejsou), ale proto, že jsou definovány výčet možné hodnoty proměnné tohoto typu.

(Vlastně, to je o něco složitější než to - enum typy jsou považovány za "základní" integer typ, což znamená, že každá enum hodnota odpovídá celočíselné hodnotě (to je typicky implicitní, ale může být manuálně specifikováno). tak, abyste mohli do proměnné enum vkládat věci libovolné celé číslo tohoto typu, i když to není "pojmenovaná" hodnota.)

Metoda System.Enum.GetNames může být použita k načtení pole řetězců, které jsou názvy hodnot enum, jak název napovídá.

EDIT: Měli namísto toho navrhnout metodu System.Enum.GetValues ​​ . Jejda.

1
Emily Chen

Můžete také svázat veřejné statické členy výčtu přímo pomocí odrazu:

typeof(Suit).GetMembers(BindingFlags.Public | BindingFlags.Static)
    .ToList().ForEach(x => DoSomething(x.Name));
0
Termininja