获取 .NET 中的枚举类型 class
Get type of enum in .NET class
考虑以下 C# class 声明:
public class MyClass {
private enum Colours { Red, Green, Blue }
}
坐在单独的 class library/DLL.
仅给定 typeof(MyClass) 对象 (System.Type),有没有办法在运行时检查 class 是否包含名为 Colors 的枚举,如果是 return 它是相应的 System.Type 对象?
我想做的是编写一些通用代码,给定类型 class 并确定内部是否包含专门命名的枚举,然后查询枚举中的值。
我知道如何使用反射来查询诸如 GetFields、GetProperties 等内容,但是 System.Type 中没有 GetClasses 或 GetEnums 方法。
我怀疑程序集中有这种信息?
就这样:
var res = typeof(MyClass).GetNestedType("Colours", BindingFlags.NonPublic);
测试res != null
以查看是否存在这种类型。
然后测试res.IsEnum
看嵌套类型是否是枚举。
补充:如果嵌套类型偶尔嵌套public,请改用BindingFlags.NonPublic | BindingFlags.Public
。
var types = typeof(MyClass).Assembly.DefinedTypes;
foreach (var type in types)
{
Console.WriteLine(type.Name);
}
输出:
MyClass
Colours
我想到了以下两种方法:
public class MyClass {
private enum Colours { Red, Green, Blue }
private class Inner {
private enum Colours { Black, White }
}
}
class Program {
static void Main(string[] args) {
Type coloursType;
// 1. enumerator
coloursType = typeof(MyClass).EnumerateNestedTypes()
.Where(t => t.Name == "Colours" && t.IsEnum)
.FirstOrDefault();
// 2. search method
coloursType = typeof(MyClass).FindNestedType(t => t.Name == "Colours" && t.IsEnum);
if(coloursType != null) {
Console.WriteLine(string.Join(", ", coloursType.GetEnumNames()));
} else {
Console.WriteLine("Type not found");
}
Console.ReadKey();
}
}
public static class Extensions {
public static IEnumerable<Type> EnumerateNestedTypes(this Type type) {
const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic;
Queue<Type> toBeVisited = new Queue<Type>();
toBeVisited.Enqueue(type);
do {
Type[] nestedTypes = toBeVisited.Dequeue().GetNestedTypes(flags);
for(int i = 0, l = nestedTypes.Length; i < l; i++) {
Type t = nestedTypes[i];
yield return t;
toBeVisited.Enqueue(t);
}
} while(toBeVisited.Count != 0);
}
public static Type FindNestedType(this Type type, Predicate<Type> filter) {
const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic;
Type[] nestedTypes = type.GetNestedTypes(flags);
foreach(var nestedType in nestedTypes) {
if(filter(nestedType)) {
return nestedType;
}
}
foreach(var nestedType in nestedTypes) {
Type result = FindNestedType(nestedType, filter);
if(result != null) {
return result;
}
}
return null;
}
}
考虑以下 C# class 声明:
public class MyClass {
private enum Colours { Red, Green, Blue }
}
坐在单独的 class library/DLL.
仅给定 typeof(MyClass) 对象 (System.Type),有没有办法在运行时检查 class 是否包含名为 Colors 的枚举,如果是 return 它是相应的 System.Type 对象?
我想做的是编写一些通用代码,给定类型 class 并确定内部是否包含专门命名的枚举,然后查询枚举中的值。
我知道如何使用反射来查询诸如 GetFields、GetProperties 等内容,但是 System.Type 中没有 GetClasses 或 GetEnums 方法。
我怀疑程序集中有这种信息?
就这样:
var res = typeof(MyClass).GetNestedType("Colours", BindingFlags.NonPublic);
测试res != null
以查看是否存在这种类型。
然后测试res.IsEnum
看嵌套类型是否是枚举。
补充:如果嵌套类型偶尔嵌套public,请改用BindingFlags.NonPublic | BindingFlags.Public
。
var types = typeof(MyClass).Assembly.DefinedTypes;
foreach (var type in types)
{
Console.WriteLine(type.Name);
}
输出:
MyClass
Colours
我想到了以下两种方法:
public class MyClass {
private enum Colours { Red, Green, Blue }
private class Inner {
private enum Colours { Black, White }
}
}
class Program {
static void Main(string[] args) {
Type coloursType;
// 1. enumerator
coloursType = typeof(MyClass).EnumerateNestedTypes()
.Where(t => t.Name == "Colours" && t.IsEnum)
.FirstOrDefault();
// 2. search method
coloursType = typeof(MyClass).FindNestedType(t => t.Name == "Colours" && t.IsEnum);
if(coloursType != null) {
Console.WriteLine(string.Join(", ", coloursType.GetEnumNames()));
} else {
Console.WriteLine("Type not found");
}
Console.ReadKey();
}
}
public static class Extensions {
public static IEnumerable<Type> EnumerateNestedTypes(this Type type) {
const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic;
Queue<Type> toBeVisited = new Queue<Type>();
toBeVisited.Enqueue(type);
do {
Type[] nestedTypes = toBeVisited.Dequeue().GetNestedTypes(flags);
for(int i = 0, l = nestedTypes.Length; i < l; i++) {
Type t = nestedTypes[i];
yield return t;
toBeVisited.Enqueue(t);
}
} while(toBeVisited.Count != 0);
}
public static Type FindNestedType(this Type type, Predicate<Type> filter) {
const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic;
Type[] nestedTypes = type.GetNestedTypes(flags);
foreach(var nestedType in nestedTypes) {
if(filter(nestedType)) {
return nestedType;
}
}
foreach(var nestedType in nestedTypes) {
Type result = FindNestedType(nestedType, filter);
if(result != null) {
return result;
}
}
return null;
}
}