Q:

GetType returns diffent information than is operator uses

Cannot explain what is going on the following program. GetType is returning the type I want to return and not the original one. Does that mean we cannot rely on GetType? is operator is right though. Can anybody please explain it in detail?
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?
        }

    }
}
}

Update: I am reading the book CLR via C# 3rd edition. In chapter 4 (2nd page) when it explains different methods in System.Object it says 

"The GetType method is nonvirtual,
  which prevents a class overriding this
  method and lying about its type"

While I agree about the first statement, I am lying about MyClass type. ain't I?

A:

Please take care of the warning, as they do exists for reasons. Your code compiled with the following warning:
Warning    1   'ConsoleApplication2.MyClass.GetType()' hides inherited member 'object.GetType()'. Use the new keyword if hiding was intended.
which means GetType() is non-virtual and you are writing new unrelated method of GetType() that CLR will never call it. 

A:

is operator implemented in terms of as operator and finally use isinst IL instruction. And of course this instruction don't know about your not virtual GetType method that you define in some class in your inheritance hierarchy.
To understand this "confusing" behavior lets "implement" our own version of the "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();
    }            
}

A:

Object.GetType is not a virtual method.  So mc is MyClass and effectively calls Object.GetType and not your method.

