为什么Object.GetType()不是虚拟的?

时间:2010-07-15 07:24:35

标签: c# .net architecture

从MSDN获取的代码示例

public class Test {
public static void Main() {
  MyBaseClass myBase = new MyBaseClass();
  MyDerivedClass myDerived = new MyDerivedClass();
  object o = myDerived;
  MyBaseClass b = myDerived;

  Console.WriteLine("mybase: Type is {0}", myBase.GetType());
  Console.WriteLine("myDerived: Type is {0}", myDerived.GetType());
  Console.WriteLine("object o = myDerived: Type is {0}", o.GetType());
  Console.WriteLine("MyBaseClass b = myDerived: Type is {0}", b.GetType());   }}

/*
This code produces the following output.
mybase: Type is MyBaseClass
myDerived: Type is MyDerivedClass
object o = myDerived: Type is MyDerivedClass
MyBaseClass b = myDerived: Type is MyDerivedClass 
*/

因此,使GetType()虚拟至少它作为虚拟工作是合乎逻辑的吗?任何人都可以解释一下吗? 和其他问题.NET框架中的任何其他方法都有类似GetType的行为吗?

5 个答案:

答案 0 :(得分:17)

因为.Net框架不希望您覆盖类型的GetType()方法和spoof

假设您可以覆盖该方法除了返回实例的类型之外还希望它做什么。当你为每个类重写方法以返回实例的类型时,你不会违反DRY。

答案 1 :(得分:2)

GetType返回对象的实际类型。这允许我们知道我们真正传递给'我们'函数的对象。框架的许多方法都需要这个来确定它们自己的功能 - 在大多数情况下需要获取此类的属性。 如果框架失去了确定对象的实际类型的可能性,那么该对象也将失去此类型

如果您想知道方法范围中使用的类型 - 您声明的类型或编译器选择的类型 - 您可以添加一个非常简单的扩展方法:

public static Type GetCurrentType<T>(this T obj)
{
    return typeof(T);
}

public static void Main()
{
  MyBaseClass myBase = new MyBaseClass();
  MyDerivedClass myDerived = new MyDerivedClass();
  object o = myDerived;
  MyBaseClass b = myDerived;

  Console.WriteLine("mybase: Type is {0}", myBase.GetCurrentType());
  Console.WriteLine("myDerived: Type is {0}", myDerived.GetCurrentType());
  Console.WriteLine("object o = myDerived: Type is {0}", o.GetCurrentType());
  Console.WriteLine("MyBaseClass b = myDerived: Type is {0}", b.GetCurrentType());
}

/*
This code produces the following output.
mybase: Type is ValidatorTest.MyBaseClass
myDerived: Type is ValidatorTest.MyDerivedClass
object o = myDerived: Type is System.Object
MyBaseClass b = myDerived: Type is ValidatorTest.MyBaseClass
*/

答案 2 :(得分:2)

如果GetType()是虚拟的,名为HumanBeing的类可以覆盖它并返回一个表示Robot的Type对象,称为欺骗并防止这是CLR的主要功能之一类型安全。

答案 3 :(得分:2)

虽然你无法覆盖object.GetType()方法,但你可以使用“new”来完全重载它,从而欺骗另一种已知类型。这很有趣,但是,我还没有想出如何从头开始创建“Type”对象的实例,所以下面的例子假装是另一种类型。

public class NotAString
{
    private string m_RealString = string.Empty;
    public new Type GetType()
    {
        return m_RealString.GetType();
    }
}

创建此实例后,(new NotAString())。GetType()确实会返回字符串的类型。

答案 4 :(得分:0)

修改Snooze博士的answer,以便创建&#34; Type&#34;的实例。从头开始的对象&#34;:

public class NotAString
{
    public new Type GetType()
    {
        return typeof(string);
    }
}