it-swarm.com.de

Wie konvertiere ich eine Aufzählung in eine Liste in C #?

Gibt es eine Möglichkeit, ein enum in eine Liste zu konvertieren, die alle Optionen der Aufzählung enthält?

558
newWeb

Dies gibt einen IEnumerable<SomeEnum> aller Werte einer Aufzählung zurück.

Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();

Wenn Sie möchten, dass dies ein List<SomeEnum> ist, fügen Sie einfach .ToList() nach .Cast<SomeEnum>() hinzu.

Um die Cast-Funktion in einem Array verwenden zu können, muss der System.Linq in Ihrem using-Abschnitt enthalten sein.

965
Jake Pearson

Viel einfacher Weg:

Enum.GetValues(typeof(SomeEnum))
    .Cast<SomeEnum>()
    .Select(v => v.ToString())
    .ToList();
98
Gili

Die kurze Antwort lautet:

(SomeEnum[])Enum.GetValues(typeof(SomeEnum))

Wenn Sie das für eine lokale Variable benötigen, ist es var allSomeEnumValues = (SomeEnum[])Enum.GetValues(typeof(SomeEnum));.

Warum ist die Syntax so?!

Die static-Methode GetValues wurde in den alten .NET 1.0-Tagen eingeführt. Es gibt ein eindimensionales Array vom Laufzeit-Typ SomeEnum[] zurück. Da es sich jedoch um eine nicht generische Methode handelt (Generics wurde erst in .NET 2.0 eingeführt), kann der Rückgabetyp (Rückgabetyp zur Kompilierungszeit) nicht als solcher deklariert werden.

.NET-Arrays haben eine Art Kovarianz, aber weil SomeEnum ein Werttyp ist und weil die Kovarianz des Arraytyps es tut Funktioniert nicht mit Werttypen, kann der Rückgabetyp nicht einmal als object[] oder Enum[] deklariert werden. (Dies unterscheidet sich von z. B. diese Überladung von GetCustomAttributes aus .NET 1. , die den Rückgabetyp object[] zur Kompilierungszeit hat, aber tatsächlich ein Array vom Typ SomeAttribute[] zurückgibt, wobei SomeAttribute notwendigerweise a ist Referenztyp.)

Aus diesem Grund musste die .NET 1.0-Methode ihren Rückgabetyp als System.Array deklarieren. Aber ich garantiere dir, es ist ein SomeEnum[].

Jedes Mal, wenn Sie GetValues mit demselben Aufzählungstyp erneut aufrufen, muss ein neues Array zugewiesen und die Werte in das neue Array kopiert werden. Dies liegt daran, dass Arrays möglicherweise vom "Consumer" der Methode geschrieben (geändert) werden, sodass ein neues Array erstellt werden muss, um sicherzustellen, dass die Werte unverändert bleiben. .NET 1.0 hatte keine guten Nur-Lese-Sammlungen.

Wenn Sie die Liste aller Werte an vielen verschiedenen Stellen benötigen, sollten Sie GetValues nur einmal aufrufen und das Ergebnis in einem schreibgeschützten Wrapper zwischenspeichern. Beispiel:

public static readonly ReadOnlyCollection<SomeEnum> AllSomeEnumValues
    = Array.AsReadOnly((SomeEnum[])Enum.GetValues(typeof(SomeEnum)));

Dann können Sie AllSomeEnumValues viele Male verwenden und dieselbe Sammlung kann sicher wiederverwendet werden.

Warum ist es schlecht, .Cast<SomeEnum>() zu verwenden?

Viele andere Antworten verwenden .Cast<SomeEnum>(). Das Problem dabei ist, dass die nicht generische Implementierung von IEnumerable der Klasse Array verwendet wird. Dies sollte bedeutet, dass jeder der Werte in ein System.Object -Feld eingepackt wurde und anschließend mit der Cast<> -Methode alle diese Werte wieder entpackt wurden. Glücklicherweise scheint die .Cast<> -Methode den Laufzeittyp ihres Parameters IEnumerable (des Parameters this) zu überprüfen, bevor sie die Auflistung durchläuft. Es ist also nicht so schlimm. Es stellt sich heraus, dass .Cast<> dieselbe Array-Instanz durchlässt.

Wenn Sie mit .ToArray() oder .ToList() fortfahren, wie in:

Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList() // DON'T do this

sie haben ein anderes Problem: Sie erstellen eine neue Sammlung (Array), wenn Sie GetValues aufrufen, und erstellen dann noch eine neue Sammlung (List<>) mit dem Aufruf .ToList(). Das ist also eine (zusätzliche) redundante Zuordnung einer gesamten Sammlung, um die Werte zu speichern.

76

Ich liebe die Verwendung von LINQ auf folgende Weise:

public class EnumModel
{
    public int Value { get; set; }
    public string Name { get; set; }
}

public enum MyEnum
{
    Name1=1,
    Name2=2,
    Name3=3
}

public class Test
{
        List<EnumModel> enums = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Select(c => new EnumModel() { Value = (int)c, Name = c.ToString() }).ToList();

        // A list of Names only, does away with the need of EnumModel 
        List<string> MyNames = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Select(c => c.ToString()).ToList();

        // A list of Values only, does away with the need of EnumModel 
        List<int> myValues = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Select(c => (int)c).ToList();

        // A dictionnary of <string,int>
        Dictionary<string,int> myDic = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).ToDictionary(k => k.ToString(), v => (int)v);
}

Ich hoffe es hilft

29
Booster2ooo
List <SomeEnum> theList = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList();
20
luisetxenike

sehr einfache Antwort

Hier ist eine Eigenschaft, die ich in einer meiner Anwendungen verwende

public List<string> OperationModes
{
    get
    {
       return Enum.GetNames(typeof(SomeENUM)).ToList();
    }
}
11
Tyler
Language[] result = (Language[])Enum.GetValues(typeof(Language))
5

Ich habe immer eine Liste von enum Werten wie folgt erhalten:

Array list = Enum.GetValues(typeof (SomeEnum));
5

Hier aus Gründen der Nützlichkeit ... Code zum Abrufen der Werte in einer Liste, mit dem die Aufzählung in eine lesbare Form für den Text konvertiert wird

public class KeyValuePair
  {
    public string Key { get; set; }

    public string Name { get; set; }

    public int Value { get; set; }

    public static List<KeyValuePair> ListFrom<T>()
    {
      var array = (T[])(Enum.GetValues(typeof(T)).Cast<T>());
      return array
        .Select(a => new KeyValuePair
          {
            Key = a.ToString(),
            Name = a.ToString().SplitCapitalizedWords(),
            Value = Convert.ToInt32(a)
          })
          .OrderBy(kvp => kvp.Name)
         .ToList();
    }
  }

.. und die unterstützende System.String-Erweiterungsmethode:

/// <summary>
/// Split a string on each occurrence of a capital (assumed to be a Word)
/// e.g. MyBigToe returns "My Big Toe"
/// </summary>
public static string SplitCapitalizedWords(this string source)
{
  if (String.IsNullOrEmpty(source)) return String.Empty;
  var newText = new StringBuilder(source.Length * 2);
  newText.Append(source[0]);
  for (int i = 1; i < source.Length; i++)
  {
    if (char.IsUpper(source[i]))
      newText.Append(' ');
    newText.Append(source[i]);
  }
  return newText.ToString();
}
5
public class NameValue
{
    public string Name { get; set; }
    public object Value { get; set; }
}

public class NameValue
{
    public string Name { get; set; }
    public object Value { get; set; }
}

public static List<NameValue> EnumToList<T>()
{
    var array = (T[])(Enum.GetValues(typeof(T)).Cast<T>()); 
    var array2 = Enum.GetNames(typeof(T)).ToArray<string>(); 
    List<NameValue> lst = null;
    for (int i = 0; i < array.Length; i++)
    {
        if (lst == null)
            lst = new List<NameValue>();
        string name = array2[i];
        T value = array[i];
        lst.Add(new NameValue { Name = name, Value = value });
    }
    return lst;
}

In eine Liste konvertieren Weitere Informationen verfügbar hier .

4
Kiarash
private List<SimpleLogType> GetLogType()
{
  List<SimpleLogType> logList = new List<SimpleLogType>();
  SimpleLogType internalLogType;
  foreach (var logtype in Enum.GetValues(typeof(Log)))
  {
    internalLogType = new SimpleLogType();
    internalLogType.Id = (int) (Log) Enum.Parse(typeof (Log), logtype.ToString(), true);
    internalLogType.Name = (Log)Enum.Parse(typeof(Log), logtype.ToString(), true);
    logList.Add(internalLogType);
  }
  return logList;
}

im oberen Code ist Log eine Aufzählung und SimpleLogType ist eine Struktur für Protokolle.

public enum Log
{
  None = 0,
  Info = 1,
  Warning = 8,
  Error = 3
}
2
/// <summary>
/// Method return a read-only collection of the names of the constants in specified enum
/// </summary>
/// <returns></returns>
public static ReadOnlyCollection<string> GetNames()
{
    return Enum.GetNames(typeof(T)).Cast<string>().ToList().AsReadOnly();   
}

wobei T eine Art von Aufzählung ist; Füge das hinzu:

using System.Collections.ObjectModel; 
1
frigate

Wenn Sie Enum int als Schlüssel und name als Wert haben möchten, ist dies gut, wenn Sie die Nummer in der Datenbank speichern und sie von Enum stammt!

void Main()
{
     ICollection<EnumValueDto> list = EnumValueDto.ConvertEnumToList<SearchDataType>();

     foreach (var element in list)
     {
        Console.WriteLine(string.Format("Key: {0}; Value: {1}", element.Key, element.Value));
     }

     /* OUTPUT:
        Key: 1; Value: Boolean
        Key: 2; Value: DateTime
        Key: 3; Value: Numeric         
     */
}

public class EnumValueDto
{
    public int Key { get; set; }

    public string Value { get; set; }

    public static ICollection<EnumValueDto> ConvertEnumToList<T>() where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum)
        {
            throw new Exception("Type given T must be an Enum");
        }

        var result = Enum.GetValues(typeof(T))
                         .Cast<T>()
                         .Select(x =>  new EnumValueDto { Key = Convert.ToInt32(x), 
                                       Value = x.ToString(new CultureInfo("en")) })
                         .ToList()
                         .AsReadOnly();

        return result;
    }
}

public enum SearchDataType
{
    Boolean = 1,
    DateTime,
    Numeric
}
1
xajler

Sie können die folgende generische Methode verwenden:

public static List<T> GetItemsList<T>(this int enums) where T : struct, IConvertible
{
    if (!typeof (T).IsEnum)
    {
        throw new Exception("Type given must be an Enum");
    }

    return (from int item in Enum.GetValues(typeof (T))
            where (enums & item) == item
            select (T) Enum.Parse(typeof (T), item.ToString(new CultureInfo("en")))).ToList();
}
0
Vitall