如何在C#中将枚举转换为列表?

有没有办法将enum转换为包含所有枚举选项的列表?

554983 次浏览

这将返回一个枚举的所有值的IEnumerable<SomeEnum>

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

如果您希望它是List<SomeEnum>,只需在.Cast<SomeEnum>()之后添加.ToList()

要在数组上使用Cast函数,您需要在使用部分中包含System.Linq

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

转换枚举到列表更多可用信息这里

更简单的方法:

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

这里是为了有用性……一些将值放入列表的代码,它将枚举转换为文本的可读形式

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

…和支持的System. String扩展方法:

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

我总是使用enum值的列表,如下所示:

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

您可以使用以下泛型方法:

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

其中T是一种枚举类型; 添加此:

using System.Collections.ObjectModel;

如果您想要Enum int作为键和name作为值,那么如果您将数字存储到数据库并且它来自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
}

非常简单的答案

这是我在一个应用程序中使用的属性

public List<string> OperationModes
{
get
{
return Enum.GetNames(typeof(SomeENUM)).ToList();
}
}

这是我喜欢的方式,使用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);
}

希望有帮助

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

在顶部代码中,日志是枚举,SimpleLogType是日志的结构。

public enum Log
{
None = 0,
Info = 1,
Warning = 8,
Error = 3
}

简短的回答是,使用:

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

如果你需要一个局部变量,它是var allSomeEnumValues = (SomeEnum[])Enum.GetValues(typeof(SomeEnum));

为什么语法是这样的?!

static方法GetValues是在旧的. NET 1.0天引入的。它返回运行时类型SomeEnum[]的一维数组。但由于它是一个非泛型方法(泛型直到. NET 2.0才引入),它不能声明其返回类型(编译时返回类型)。

. NET数组确实有一种协方差,但是因为SomeEnum将是值类型,并且因为数组类型协方差不适用于值类型,它们甚至不能将返回类型声明为object[]Enum[]。(这与例如来自. NET 1.0的GetCustomAttributes重载不同,它具有编译时返回类型object[],但实际上返回类型为SomeAttribute[]的数组,其中SomeAttribute必然是引用类型。)

因此,. NET 1.0方法必须将其返回类型声明为System.Array。但我向您保证它是SomeEnum[]

每次使用相同的枚举类型再次调用GetValues时,它都必须分配一个新数组并将值复制到新数组中。这是因为数组可能被方法的“消费者”写入(修改),因此它们必须创建一个新数组以确保值保持不变。. NET 1.0没有良好的只读集合。

如果您需要许多不同位置的所有值列表,请考虑调用GetValues一次并将结果缓存在只读包装器中,例如:

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

然后您可以多次使用AllSomeEnumValues,并且可以安全地重复使用相同的集合。

为什么使用.Cast<SomeEnum>()不好?

许多其他答案使用.Cast<SomeEnum>()。这个问题是它使用了Array类的非泛型IEnumerable实现。这个应该涉及将每个值装箱到System.Object框中,然后使用Cast<>方法再次取消所有这些值的装箱。幸运的是,.Cast<>方法似乎在开始迭代集合之前检查了其IEnumerable参数(this参数)的运行时类型,所以它毕竟没有那么糟糕。事实证明.Cast<>让同一个数组实例通过。

如果您跟随.ToArray().ToList(),如:

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

你还有另一个问题:当你调用GetValues时,你创建了一个新的集合(数组),然后使用.ToList()调用创建了一个新的集合(List<>)。所以这是一个(额外的)冗余分配整个集合来保存值。


更新:自. NET 5.0(从2020年开始)以来,上述信息已过时;终于有了一个泛型方法(泛型已从2005年的. NET Framework 2.0中引入),因此现在您应该简单地使用:

Enum.GetValues<SomeEnum>()

其返回参数是强类型的(如SomeEnum[])。

Language[] result = (Language[])Enum.GetValues(typeof(Language))