检测泛型类型是否打开
本文关键字:是否 泛型类型 检测 | 更新日期: 2023-09-27 18:21:36
我的程序集中有很多常规的、闭合的和打开的类型。我有一个查询,我正试图从中排除开放类型
class Foo { } // a regular type
class Bar<T, U> { } // an open type
class Moo : Bar<int, string> { } // a closed type
var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => ???);
types.Foreach(t => ConsoleWriteLine(t.Name)); // should *not* output "Bar`2"
在调试开放类型的泛型参数时,我发现它们的FullName
是null(以及其他类似DeclaringMethod
的东西)-所以这可能是一种方式:
bool IsOpenType(Type type)
{
if (!type.IsGenericType)
return false;
var args = type.GetGenericArguments();
return args[0].FullName == null;
}
Console.WriteLine(IsOpenType(typeof(Bar<,>))); // true
Console.WriteLine(IsOpenType(typeof(Bar<int, string>))); // false
有没有一种内置的方法可以知道一个类型是否是打开的?如果没有,有更好的方法吗?谢谢
您可以使用IsGenericTypeDefinition
:
typeof(Bar<,>).IsGenericTypeDefinition // true
typeof(Bar<int, string>).IsGenericTypeDefinition // false
Type.IsGenericTypeDefinition在技术上不是排除开放类型的正确属性。然而,在你的情况下(实际上在大多数其他情况下),它会很好地工作。
也就是说,一个类型可以是开放的,而不是泛型类型定义。在更一般的情况下,例如在接受Type参数的公共方法中,您真正想要的是Type.ContainsGenericParameters.
有关详细信息,请参阅此问题的答案:
Type.IsGenericTypeDefinition和Type.ContainsGenericParameters 之间的差异
TL;DR:后者是递归的,而前者不是,因此可以通过构造一个将泛型类型定义作为其泛型类型参数之一的泛型类型来"愚弄"它。