繁体   English   中英

检测泛型类型是否已打开?

[英]Detect if a generic type is open?

我的程序集中有一堆常规,封闭和打开的类型。 我有一个查询,我试图排除它的开放类型

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是空(以及其他的东西,如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:后者是递归的,而前者不是,因此可以通过构造具有泛型类型定义作为其至少一个泛型类型参数的泛型类型来“欺骗”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM