确定类型是否为枚举类型的通用列表
Determine if a Type is a Generic List of Enum Types
我需要确定给定类型是否为枚举类型的泛型列表。
我想出了以下代码:
void Main()
{
TestIfListOfEnum(typeof(int));
TestIfListOfEnum(typeof(DayOfWeek[]));
TestIfListOfEnum(typeof(List<int>));
TestIfListOfEnum(typeof(List<DayOfWeek>));
TestIfListOfEnum(typeof(List<DayOfWeek>));
TestIfListOfEnum(typeof(IEnumerable<DayOfWeek>));
}
void TestIfListOfEnum(Type type)
{
Console.WriteLine("Object Type: \"{0}\", List of Enum: {1}", type, IsListOfEnum(type));
}
bool IsListOfEnum(Type type)
{
var itemInfo = type.GetProperty("Item");
return (itemInfo != null) ? itemInfo.PropertyType.IsEnum : false;
}
以上代码的输出如下:
Object Type: "System.Int32", List of Enum: False
Object Type: "System.DayOfWeek[]", List of Enum: False
Object Type: "System.Collections.Generic.List`1[System.Int32]", List of Enum: False
Object Type: "System.Collections.Generic.List`1[System.DayOfWeek]", List of Enum: True
Object Type: "System.Collections.Generic.List`1[System.DayOfWeek]", List of Enum: True
Object Type: "System.Collections.Generic.IEnumerable`1[System.DayOfWeek]", List of Enum: False
除最后一个示例外,所有输出都是我想要的。它没有检测到 typeof(IEnumerable<DayOfWeek>)
是枚举类型的集合。
有谁知道我如何检测最后一个示例中的枚举类型?
如果你想测试它,给定一个类型,那么它是 IEnumerable<T>
类型,其中 T
是一个 enum
,你可以执行以下操作。
首先,获取可枚举类型的方法:
public static IEnumerable<Type> GetEnumerableTypes(Type type)
{
if (type.IsInterface)
{
if (type.IsGenericType
&& type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
yield return type.GetGenericArguments()[0];
}
}
foreach (Type intType in type.GetInterfaces())
{
if (intType.IsGenericType
&& intType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
yield return intType.GetGenericArguments()[0];
}
}
}
然后:
public static bool IsEnumerableOfEnum(Type type)
{
return GetEnumerableTypes(type).Any(t => t.IsEnum);
}
您可以像这样获取 IEnumerable<T>
的类型:
Type enumerableType = enumerable.GetType().GenericTypeArguments[0];
然后您可以通过检查该类型是否可分配给类型 Enum
的变量来测试它是否是枚举,枚举的基础 class:
typeof(Enum).IsAssignableFrom(enumerableType)
这是一个简单的方法:
public static bool TestIfSequenceOfEnum(Type type)
{
return (type.IsInterface ? new[] { type } : type.GetInterfaces())
.Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>))
.Any(i => i.GetGenericArguments().First().IsEnum);
}
基本上,提取该类型实现的所有接口,找到所有 IEnumerable<T>
和 return true
如果这些 T
中的任何一个是枚举。请记住,一个具体的 class 可能会多次实施 IEnumerable<T>
(使用不同的 T
)。
如果 type
是一个 class 或者它是一个接口,这都有效。
我需要确定给定类型是否为枚举类型的泛型列表。
我想出了以下代码:
void Main()
{
TestIfListOfEnum(typeof(int));
TestIfListOfEnum(typeof(DayOfWeek[]));
TestIfListOfEnum(typeof(List<int>));
TestIfListOfEnum(typeof(List<DayOfWeek>));
TestIfListOfEnum(typeof(List<DayOfWeek>));
TestIfListOfEnum(typeof(IEnumerable<DayOfWeek>));
}
void TestIfListOfEnum(Type type)
{
Console.WriteLine("Object Type: \"{0}\", List of Enum: {1}", type, IsListOfEnum(type));
}
bool IsListOfEnum(Type type)
{
var itemInfo = type.GetProperty("Item");
return (itemInfo != null) ? itemInfo.PropertyType.IsEnum : false;
}
以上代码的输出如下:
Object Type: "System.Int32", List of Enum: False
Object Type: "System.DayOfWeek[]", List of Enum: False
Object Type: "System.Collections.Generic.List`1[System.Int32]", List of Enum: False
Object Type: "System.Collections.Generic.List`1[System.DayOfWeek]", List of Enum: True
Object Type: "System.Collections.Generic.List`1[System.DayOfWeek]", List of Enum: True
Object Type: "System.Collections.Generic.IEnumerable`1[System.DayOfWeek]", List of Enum: False
除最后一个示例外,所有输出都是我想要的。它没有检测到 typeof(IEnumerable<DayOfWeek>)
是枚举类型的集合。
有谁知道我如何检测最后一个示例中的枚举类型?
如果你想测试它,给定一个类型,那么它是 IEnumerable<T>
类型,其中 T
是一个 enum
,你可以执行以下操作。
首先,获取可枚举类型的方法:
public static IEnumerable<Type> GetEnumerableTypes(Type type)
{
if (type.IsInterface)
{
if (type.IsGenericType
&& type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
yield return type.GetGenericArguments()[0];
}
}
foreach (Type intType in type.GetInterfaces())
{
if (intType.IsGenericType
&& intType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
yield return intType.GetGenericArguments()[0];
}
}
}
然后:
public static bool IsEnumerableOfEnum(Type type)
{
return GetEnumerableTypes(type).Any(t => t.IsEnum);
}
您可以像这样获取 IEnumerable<T>
的类型:
Type enumerableType = enumerable.GetType().GenericTypeArguments[0];
然后您可以通过检查该类型是否可分配给类型 Enum
的变量来测试它是否是枚举,枚举的基础 class:
typeof(Enum).IsAssignableFrom(enumerableType)
这是一个简单的方法:
public static bool TestIfSequenceOfEnum(Type type)
{
return (type.IsInterface ? new[] { type } : type.GetInterfaces())
.Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>))
.Any(i => i.GetGenericArguments().First().IsEnum);
}
基本上,提取该类型实现的所有接口,找到所有 IEnumerable<T>
和 return true
如果这些 T
中的任何一个是枚举。请记住,一个具体的 class 可能会多次实施 IEnumerable<T>
(使用不同的 T
)。
如果 type
是一个 class 或者它是一个接口,这都有效。