Est-il possible de convertir un enum
en une liste contenant toutes les options de l'énum?
Cela retournera un IEnumerable<SomeEnum>
de toutes les valeurs d'un Enum.
Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();
Si vous voulez que ce soit un List<SomeEnum>
, ajoutez simplement .ToList()
après .Cast<SomeEnum>()
.
Pour utiliser la fonction Cast sur un tableau, vous devez avoir le System.Linq
dans votre section using.
Manière beaucoup plus facile:
Enum.GetValues(typeof(SomeEnum))
.Cast<SomeEnum>()
.Select(v => v.ToString())
.ToList();
La réponse courte est, utilisez:
(SomeEnum[])Enum.GetValues(typeof(SomeEnum))
Si vous avez besoin de cela pour une variable locale, c'est var allSomeEnumValues = (SomeEnum[])Enum.GetValues(typeof(SomeEnum));
.
Pourquoi la syntaxe est-elle la suivante?!
La méthode static
GetValues
a été réintroduite dans les anciens jours .NET 1.0. Il retourne un tableau unidimensionnel de type à l'exécution SomeEnum[]
. Mais comme il s'agit d'une méthode non générique (les génériques n'ont pas été introduits avant .NET 2.0), il ne peut pas déclarer son type de retour (type de retour à la compilation) en tant que tel.
Les tableaux .NET ont une sorte de covariance, mais parce que SomeEnum
sera un type (-) et Comme la covariance des types de tableaux ne fonctionne pas avec les types de valeur, ils ne pouvaient même pas déclarer le type de retour sous la forme object[]
ou Enum[]
. (Ceci est différent de par exemple cette surcharge de GetCustomAttributes
from .NET 1. qui a le type de retour à la compilation object[]
mais renvoie en réalité un tableau de type SomeAttribute[]
où SomeAttribute
est nécessairement un Type de référence.)
De ce fait, la méthode .NET 1.0 devait déclarer son type de retour sous la forme System.Array
. Mais je vous garantis que c’est un SomeEnum[]
.
Chaque fois que vous appelez à nouveau GetValues
avec le même type enum, il devra allouer un nouveau tableau et copier les valeurs dans le nouveau tableau. Cela est dû au fait que les tableaux peuvent être modifiés (modifiés) par le "consommateur" de la méthode, ils doivent donc créer un nouveau tableau pour être sûrs que les valeurs sont inchangées. .NET 1.0 n'avait pas de bonnes collections en lecture seule.
Si vous avez besoin de la liste de toutes les valeurs à plusieurs endroits différents, envisagez d'appeler GetValues
une seule fois et mettez le résultat en cache dans un wrapper en lecture seule, par exemple:
public static readonly ReadOnlyCollection<SomeEnum> AllSomeEnumValues
= Array.AsReadOnly((SomeEnum[])Enum.GetValues(typeof(SomeEnum)));
Ensuite, vous pouvez utiliser AllSomeEnumValues
plusieurs fois et la même collection peut être réutilisée en toute sécurité.
Pourquoi est-il mauvais d'utiliser .Cast<SomeEnum>()
?
Beaucoup d'autres réponses utilisent .Cast<SomeEnum>()
. Le problème, c'est qu'il utilise l'implémentation non générique IEnumerable
de la classe Array
. Cela aurait dû impliquer la mise en boîte de chacune des valeurs dans une zone System.Object
, puis l'utilisation de la méthode Cast<>
pour décompresser à nouveau toutes ces valeurs. Heureusement, la méthode .Cast<>
semble vérifier le type d'exécution de son paramètre IEnumerable
(paramètre this
) avant de commencer à parcourir la collection, de sorte qu'il n'est pas si mal après tout. .Cast<>
laisse passer la même instance de tableau.
Si vous le suivez par .ToArray()
ou .ToList()
, comme dans:
Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList() // DON'T do this
vous avez un autre problème: vous créez une nouvelle collection (tableau) lorsque vous appelez GetValues
, puis créez une nouvelle collection (List<>
) avec l'appel .ToList()
. Il s’agit donc d’une allocation redondante (supplémentaire) de toute une collection pour conserver les valeurs.
Voici comment j'aime utiliser LINQ:
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);
}
J'espère que ça aide
List <SomeEnum> theList = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList();
réponse très simple
Voici une propriété que j'utilise dans l'une de mes applications
public List<string> OperationModes
{
get
{
return Enum.GetNames(typeof(SomeENUM)).ToList();
}
}
Language[] result = (Language[])Enum.GetValues(typeof(Language))
J'ai toujours eu l'habitude d'obtenir une liste de valeurs enum
comme celle-ci:
Array list = Enum.GetValues(typeof (SomeEnum));
Voici pour l'utilité ... du code pour obtenir les valeurs dans une liste, qui convertit l'énum en forme lisible pour le texte
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();
}
}
.. et la méthode d'extension System.String associée:
/// <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();
}
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;
}
Convert Enum À une liste plus d'informations disponibles ici .
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;
}
dans Code, Log est un enum et SimpleLogType est une structure pour les journaux.
public enum Log
{
None = 0,
Info = 1,
Warning = 8,
Error = 3
}
/// <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();
}
où T est un type d'énumération; Ajoute ça:
using System.Collections.ObjectModel;
Si vous voulez Enum int en tant que clé et nom en tant que valeur, c'est bien si vous stockez le numéro dans la base de données et qu'il provient d'Enum!
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
}
Vous pouvez utiliser la méthode générique suivante:
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();
}