GetType возвращает различную информацию, чем использует оператор - PullRequest
2 голосов
/ 02 октября 2010

Не могу объяснить, что происходит в следующей программе.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?
        }

    }
}
}

Обновление : Я читаю книгу CLR через C # 3-е издание.В главе 4 (2-я страница), когда он объясняет различные методы в System.Object, он говорит

«Метод GetType не является виртуальным, что предотвращает переопределение этого метода классом и ложь о его типе»

Хотя я согласен с первым утверждением, я лгу о типе MyClass.не я?

Ответы [ 6 ]

4 голосов
/ 02 октября 2010

является оператором, реализованным в виде оператора и, наконец, использует инструкцию isinst IL.И, конечно, эта инструкция не знает о вашем не виртуальном методе GetType, который вы определили в каком-то классе в иерархии наследования.

Чтобы понять это «запутанное» поведение, давайте «реализуем» нашу собственную версиюоператор ":

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();
    }            
}
4 голосов
/ 02 октября 2010

Пожалуйста, позаботьтесь о предупреждении, так как оно существует по причинам.Ваш код скомпилирован со следующим предупреждением:

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

, что означает, что GetType() не является виртуальным, и вы пишете новый несвязанный метод GetType(), который CLR никогда не вызовет.

3 голосов
/ 02 октября 2010

Object.GetType не является виртуальным методом. Так что mc is MyClass и эффективно вызывает Object.GetType, а не ваш метод.

1 голос
/ 02 октября 2010

is проверяет фактический тип времени выполнения вашей переменной.Компилятору все равно, что вы определили метод GetType (), который возвращает еще один Type.Он по-прежнему знает, что тип вашей переменной в действительности MyClass.

Что именно вы здесь пытаетесь достичь?Зачем вам нужен MyClass класс для олицетворения Program класса?

0 голосов
/ 02 октября 2010

Согласно документации, оператор 'is' не перегружен.Вот почему это, вероятно, не входит в ваш второй оператор «если».

Проверьте эту страницу из MSDN: http://msdn.microsoft.com/en-us/library/8edha89s%28v=VS.80%29.aspx

0 голосов
/ 02 октября 2010

Это будет верно, только если:

if (mc is MyClass) { ... }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...