C# 检测泛型类型是否打开?

C# 检测泛型类型是否打开?,c#,reflection,generic-type-argument,C#,Reflection,Generic Type Argument,我的程序集中有一堆常规的、封闭的和开放的类型。我有一个查询,我试图从中排除开放类型 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 => ???); ty

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

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"
是否有一种内置方法可以知道某个类型是否打开?如果没有,还有更好的方法吗?谢谢。

您可以使用:

typeof(Bar).IsGenericTypeDefinition//true
typeof(Bar).IsGenericTypeDefinition//false
从技术上讲不是排除开放类型的正确属性。但是,它在您的情况下(实际上在大多数其他情况下)会很好地工作

也就是说,类型可以是开放的,而不是泛型类型定义。在更一般的情况下,例如在接受类型参数的公共方法中,您真正想要的是

有关详细信息,请参见此问题的答案:


TL;DR:后者是递归的,而前者不是,因此可以通过构造一个泛型类型来“愚弄”它,该泛型类型至少有一个泛型类型定义作为它的泛型类型参数。

你看过
IsGenericType
的文档了吗<代码>使用ContainsGenericParameters属性确定类型对象是表示开放构造类型还是表示封闭构造类型。您需要获取所有开放类型的类型?…var types=Assembly.getExecutionGassembly().GetTypes()。其中(t=>!t.IsGenericTypeDefinition)@黑暗猎鹰:谢谢你的意见。这也行得通。我在intellisense中看到过
ContainsGenericParameters
弹出,但我认为如果该类型有任何泛型参数,则返回true。阅读文档时似乎不是这样-似乎“参数”与“参数”不同@terrybozzio不,相反,过滤掉:)在我编辑的评论中,它会过滤掉…@terrybozzio注意到,谢谢你+1:)“你可以在2分钟内接受答案…”~~~~~~~~~~继续左击click@vexe:哈哈,很乐意帮忙。刚找到这个,似乎也是另一种方式,IsConstructedGenericType@vexe:看起来它也会起作用。虽然它看起来与
IsGenericTypeDefinition
完全相反。但我不确定为什么你的答案不是公认的答案。问题显然是问一个类型是否是开放的。因为那些“半开放”类型不能被实例化,所以它们肯定不能被认为是封闭的。无论如何,对于这个答案+1:)
    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
typeof(Bar<,>).IsGenericTypeDefinition // true
typeof(Bar<int, string>).IsGenericTypeDefinition // false