GetType返回的信息不同于运算符使用的信息

时间:2010-10-02 05:34:43

标签: c# clr

无法解释以下程序的内容。 GetType返回我想要返回的类型而不是原始类型。这是否意味着我们不能依赖GetType?虽然运营商是对的。有人可以详细解释一下吗?

using System;

namespace ConsoleApplication2
{
    public class MyClass
    {
        public Type GetType()
        {
            return typeof(Program);
        }

    }

class Program
{
    static void Main(string[] args)
    {
        MyClass mc = new MyClass();

        if (mc.GetType() == typeof(Program))
        {
            Console.WriteLine("Confused."); 
        }
        if(mc is Program)
        {
            Console.WriteLine(mc.GetType()); // Don't get inside the if. Why?
        }

    }
}
}

更新:我正在通过C#第3版阅读CLR一书。在第4章(第2页)中,当它解释System.Object中的不同方法时,它说

  

“GetType方法是非虚拟的,   这会阻止一个类覆盖它   方法和谎言的类型“

虽然我同意第一个陈述,但我对MyClass类型撒谎。不是吗?

6 个答案:

答案 0 :(得分:4)

请注意警告,因为它们确实存在。您的代码使用以下警告编译:

Warning 1 'ConsoleApplication2.MyClass.GetType()' hides inherited member 'object.GetType()'. Use the new keyword if hiding was intended.

这意味着GetType()是非虚拟的,并且您正在编写新的不相关的GetType()方法,CLR永远不会将其称为{{1}}。

答案 1 :(得分:4)

is operator implemented in terms of as operator最后使用isinst IL指令。当然,此指令不了解您在继承层次结构中的某些类中定义的非虚拟GetType方法。

要理解这种“令人困惑”的行为,可以“实施”我们自己的“is operator”版本:

public class MyClass
{
    public Type GetType()
    {
        return typeof(Program);
    }

}

class Program {

    //this is oversimplified implementation,
    //but I want to show the main differences
    public static bool IsInstOf(object o, Type t)
    {
        //calling GetType on System.Object
        return o.GetType().IsAssignableFrom(t);
    }

    static void Main(string[] args)
    {
        MyClass mc = new MyClass();

        //calling MyClass non-virtual version for GetType method
        if (mc.GetType() == typeof(Program))
        {
            //Yep, this condition is true
            Console.WriteLine("Not surprised!");
        }

        //Calling System.Object non-virtual version for GetType method
        if (IsInstOf(mc, typeof(Program)))
        {
            //Nope, this condition isn't met!
            //because mc.GetType() != ((object)mc).GetType()!
        }

        Console.ReadLine();
    }            
}

答案 2 :(得分:3)

Object.GetType不是虚拟方法。所以mc is MyClass并有效地调用了Object.GetType,而不是您的方法。

答案 3 :(得分:1)

检查变量的实际运行时类型。编译器并不关心您是否定义了一个名为GetType()的方法,该方法返回另一个Type。它仍然知道变量的实际类型是MyClass

你到底想要完成什么?为什么您需要MyClass课程来模拟Program课程?

答案 4 :(得分:0)

只有在以下情况下才会出现:

if (mc is MyClass) { ... }

答案 5 :(得分:0)

根据文档,'is'运算符不可重载。这就是为什么它可能没有进入你的第二个'if'陈述。

从MSDN查看此页面: http://msdn.microsoft.com/en-us/library/8edha89s%28v=VS.80%29.aspx