【问题标题】:Detect if a generic type is open?检测泛型类型是否打开?
【发布时间】:2014-11-06 19:45:29
【问题描述】:

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

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

是否有内置方法可以知道类型是否打开?如果没有,有更好的方法吗?谢谢。

【问题讨论】:

  • 您查看过IsGenericType 的文档吗? Use the ContainsGenericParameters property to determine whether a Type object represents an open constructed type or a closed constructed type.
  • 你需要获取所有开放类型的类型吗?...var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => !t.IsGenericTypeDefinition);
  • @Dark Falcon:感谢您的意见。这也有效。我在智能感知中看到了ContainsGenericParameters pop,但我认为如果该类型有任何通用参数,它会返回 true。阅读文档似乎不是那么回事 - 似乎“参数”与“参数”不同? @terrybozzio 不,相反,将它们过滤掉:)
  • 在我编辑的评论中,它会将它们过滤掉......
  • @terrybozzio 注意到了,谢谢 +1 :)

标签: c# reflection generic-type-argument


【解决方案1】:

你可以使用IsGenericTypeDefinition:

typeof(Bar<,>).IsGenericTypeDefinition // true
typeof(Bar<int, string>).IsGenericTypeDefinition // false

【讨论】:

  • "你可以在 2 分钟内接受答案..." ~____~ *继续抨击左键
  • @vexe:哈哈,很高兴为您提供帮助。
  • 刚找到这个,好像也是另一种方式 IsConstructedGenericType msdn.microsoft.com/en-us/library/…
  • @vexe:看起来它也可以。虽然它看起来与IsGenericTypeDefinition 完全相反。
【解决方案2】:

Type.IsGenericTypeDefinition 在技术上不是排除开放类型的正确属性。但是,在您的情况下(实际上在大多数其他情况下),它可以正常工作。

话虽如此,一个类型可以是开放的,而不是一个泛型类型定义。在更一般的情况下,例如在接受 Type 参数的公共方法中,您真正想要的是Type.ContainsGenericParameters

有关详细信息,请参阅此问题的答案:
Difference between Type.IsGenericTypeDefinition and Type.ContainsGenericParameters

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

【讨论】:

  • 我不确定为什么您的答案不被接受。问题显然是询问一个类型是否是开放的。由于那些“半开”类型不能被实例化,它们绝对不能被认为是封闭的。无论如何对于这个答案+1 :)
猜你喜欢
  • 2021-05-30
  • 2019-06-25
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多