【发布时间】:2011-05-13 22:36:39
【问题描述】:
我们的源代码中有一个通用组件,它包含一个非常大的应用程序的所有枚举(大约 300 个!)。
有没有什么方法可以使用 C# 或 VB.NET 来遍历所有这些以便对每个执行操作?
How to iterate all “public string” properties in a .net class 的问题几乎是相关的,但我正在处理的枚举是多种类型的混合
【问题讨论】:
我们的源代码中有一个通用组件,它包含一个非常大的应用程序的所有枚举(大约 300 个!)。
有没有什么方法可以使用 C# 或 VB.NET 来遍历所有这些以便对每个执行操作?
How to iterate all “public string” properties in a .net class 的问题几乎是相关的,但我正在处理的枚举是多种类型的混合
【问题讨论】:
类似的东西?
var query = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.IsEnum && t.IsPublic);
foreach (Type t in query)
{
Console.WriteLine(t);
}
【讨论】:
var a = Assembly.Load("MyAssembly"); 和var query = a.GetTypes().Where(t => t.IsEnum && t.IsPublic);)但是我该如何使用它们呢?所有t 都属于System.RuntimeType 类型,我想将它们用作枚举(对于所有这些反射的东西来说都很新!)
var values = new List<int>(); var names = new List<string>(); names.AddRange(Enum.GetNames(t)); values.AddRange((IEnumerable<int>) Enum.GetValues(t));
这应该可以帮助您入门。遍历加载程序集中的类型;并检查它们是否是枚举:
List<string> enumValues = new List<string>();
foreach(Type t in AppDomain.CurrentDomain.GetAssemblies().Select(a=>a.GetTypes().Where(t=>t.IsEnum)))
{
enumValues.AddRange(Enum.GetNames(t));
}
【讨论】:
Unable to cast object of type 'WhereArrayIterator1[System.Type]' to type 'System.Type'。`
加载所有程序集后,您可以遍历每个程序集并调用 GetTypes() 以返回所有类型(您也可以选择获取私有类型,尽管这会花费更长的时间)。您可以按 IsEnum 过滤类型以仅获取枚举类型。请注意,这还将返回所有 BCL Enum 类型。如果您不想要 BCL 类型,则需要将它们过滤掉。您可以通过忽略名称以“系统”开头的程序集来摆脱它们中的大多数。或者,您可以检查该路径是否包含您的本地路径,假设您的所有项目程序集对于您的 EXE 来说都是本地的。
【讨论】:
假设您拥有枚举所在的程序集。
IEnumerable<Type> enums = assembly.GetTypes.Where(t => t.IsEmum);
【讨论】:
如果你将所有的enums 编译成一个通用的enum,你可以使用类似这样的东西:
using System;
namespace SomeApp
{
class Program
{
static void Main(string[] args)
{
foreach(MyEnum target in Enum.GetValues(typeof(MyEnum)))
{
Console.WriteLine(target.ToString());
// You can obviously perform an action on each one here.
}
}
}
enum MyEnum
{
One,
Two,
Three,
Four,
Five
};
}
/*
Prints...
One
Two
Three
Four
Five
*/
希望这可以让您走上正确的道路。
【讨论】: