【问题标题】:What does GetType() return on an instance of Type?GetType() 在 Type 的实例上返回什么?
【发布时间】:2011-11-03 12:23:02
【问题描述】:

我在一些调试过程中遇到了这段代码。

private bool HasBaseType(Type type, out Type baseType)
{
    Type originalType = type.GetType();
    baseType = GetBaseType(type);
    return baseType != originalType;
}

我最初的想法是,方法的第一行中的type.GetType() 总是会产生与typeof(System.Type) 等效的结果,这在上下文中对我来说似乎毫无意义。但是,MSDN suggestsType 会覆盖将继承自 ObjectGetType() 的版本。然后,actual MSDN page on non-static Type.GetType()(不要与三个静态版本混淆)表示GetType() 方法返回“当前类型”。没有给出进一步的相关解释。

那么,上述方法中originalType的值是等于type还是等于typeof(System.Type)?从文档中我不太确定。如果originalType 等价于type,它是否是type副本,因此,如果GetBaseType 方法改变其参数,originalType 仍将等价于@987654339无论GetBaseType 内部发生什么,@ 都保持其原始形式?

【问题讨论】:

  • private bool HasBaseType(Object instance, out Type baseType)
  • 如果你想要的只是基本类型,为什么不直接使用 Type.BaseType 属性呢?
  • @tkeE2036 这段代码不是我写的;我只是在调试时发现它。而且,相信我,还有很多(可悲的)很多这是从哪里来的。

标签: c# .net-3.5 types


【解决方案1】:

1.

GetType 未定义为虚拟,因此不能被覆盖。 System.Type 不会覆盖对象的 GetType,它会隐藏它(在 C# 中,它将用 new 关键字表示)。如果你使用ILSpy之类的反汇编工具,你会看到它的实现如下:

public new Type GetType()
{
    return base.GetType();
}

如你所见,它只调用了基类(即对象)的 GetType 的实现,因此最终结果是相同的。此版本的 GetType 提供了 _Type 接口的正式实现。您通常不必担心这个接口,它是出于互操作性的原因。

2.

GetType 方法在 object 中定义并返回 System.Type。但是仔细观察 System.Type 会发现它被定义为抽象的,因此它永远不能被实例化。因此,从 GetType 获取具体内容的方法是获取另一种类型,它派生自 System.Type。事实上,我们得到的是 System.RuntimeType 的一个实例,它派生自 System.Type。

原因是必须只有一个实例代表给定类型。也就是说,无论您调用 GetType 有多少不同的字符串实例(例如),您仍然会得到完全相同的实例,因为只有一个实例描述了一个字符串。为了确保只有一个实例,System.Type 被定义为抽象,因此它不能被用户代码实例化,而 System.RuntimeType 被定义为内部,所以它只能被 mscorlib 中的代码访问,也不能被用户代码实例化。

3.

System.RuntimeType 的存在是一个实现细节,在大多数情况下可能会被忽略。出于所有意图和目的,您的代码可以假定 GetType 返回 System.Type 的实例。 唯一的例外是以下代码(您可以将字符串替换为任何其他类型):

bool b = 
    typeof(string).GetType() == typeof(Type);

如果不知道 System.RuntimeType,人们会假设 b 为真,因为它假设 GetType 返回 System.Type,这显然是右手表达式的值。但由于左边的值实际上是 System.RuntimeType,所以 b 为 false(System.Type 和 System.RuntimeType 是两种不同的类型,因此不相等)。这是您需要了解 System.RuntimeType 以了解代码为何如此运行的唯一情况。在任何其他情况下,GetType 返回 System.RuntimeType 并不重要,您可以忽略它。

4.

这是我的 .NET 在线课程中讨论运行时类型信息 (RTTI) 的部分的直接链接。我没有提到 System.RuntimeType,因为就像我说的那样,它是一个在很大程度上可以忽略的实现细节。但是这个链接会让你对 System.Type 有更多的背景和更清晰的理解。

http://motti.me/tw

我希望这会有所帮助!

莫蒂

【讨论】:

    【解决方案2】:

    Type 实例的 Type 是 System.RuntimeType。

        {
            Console.WriteLine(typeof(System.Type).GetType());
            Console.WriteLine(typeof(string).GetType().GetType());
            Console.WriteLine(typeof(int).GetType());
            Console.WriteLine(typeof(List<int>).GetType());
        }
    
    System.RuntimeType 
    System.RuntimeType 
    System.RuntimeType 
    System.RuntimeType
    

    【讨论】:

      【解决方案3】:

      看起来两者都不是。当您在 Type 实例上调用 GetType 时,它似乎总是返回 RuntimeType

      我通过运行以下代码 sn-p 来检查系统程序集:

      Assembly
        .GetAssembly(typeof(int))
        .GetTypes()
        .Where(type => type.GetType() == type)
      

      编辑: 正如 Luke 在 cmets 中阐明的那样,“原始类型”实际上只是在给定 RuntimeType 时的原始类型 - 它不适用于其他任何东西。而且由于该类型是系统内部的,因此该方法似乎完全错误。

      【讨论】:

      • 所以,如果 System.RuntimeType 的实例被传递到 OP 的方法中,那么 originalType 确实等于 type。在所有其他情况下,它们不会相等。
      • @LukeH 对。介意我编辑以包含该说明吗?
      猜你喜欢
      • 2021-04-15
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 2011-06-13
      • 1970-01-01
      相关资源
      最近更新 更多