开发者

why Object.GetType() is not virtual?

code sample taken from 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 开发者_StackOverflow中文版{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 
*/

So would it be logical to make GetType() virtual at least it works as virtual? Can anybody explaine that? And other question Is any other methods in NET framework which have behaviour alike GetType?


because .Net framework does not want you to override the GetType() method and spoof about the type.

assume you can override the method what else would you want it to do other than returning the type of the instance. and when you override the method for each of your classes to return the type of the instance, won't you violate DRY then.


While its true that you cannot override the object.GetType() method, you can use "new" to overload it completely, thereby spoofing another known type. This is interesting, however, I haven't figured out how to create an instance of the "Type" object from scratch, so the example below pretends to be another type.

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

After creating an instance of this, (new NotAString()).GetType(), will indeed return the type for a string.


GetType returns the actual Type of the object. This allows us to know what object we really got passed to 'our' function. Many methods of the framework need this to determine their own functionality - in most cases to get the Attributes of this class. If the Framework would loose the possibility to determine the real type of an object, the object would loose this type as well.

If you like to know the type used within your method scope - the type you declared or was picked by the compiler - you can add a pretty simple extension method:

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
*/


If GetType() was virtual, a class named HumanBeing can override it and return a Type object representing Robot which is called spoofing and preventing this is one of the main features of CLR called Type Safety.


Modifying Dr Snooze's answer, in order to "create an instance of the "Type" object from scratch":

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜