Почему тип "базовый" объект мой конкретный тип?

Это кажется очень простым вопросом, но, очевидно, я что-то упускаю. Я сделал тест:

class A
{
    public override int GetHashCode()
    {
        Console.WriteLine(base.GetType().Name);
        return 0;
    }
}

Я ожидал найти "объект", но я нахожу "А". Я полагался на это поведение, чтобы вызвать базу GetHashCode это конкретные случаи с реализацией, вызывая base.GetHashCode() и я ожидал object реализация должна быть вызвана.

В чем дело?

4 ответа

Решение

base. метод изменения обозначений, который вызывается для переопределения virtual методы (как GetHashCode в вашем образце - base.GetHashCode() звонки object.GetHashCode, this.GetHashCode() звонки A.GetHashCode()). base. также может использоваться для метода скрытого базового класса, но это не так в данном примере.

поскольку GetType не является виртуальным, и тогда нет вызова this.GetType() а также base.GetType() ведет себя идентично и вызывает object.GetType который возвращает "Точный тип времени выполнения текущего экземпляра", как указано в документации

Вы путаете две совершенно разные вещи здесь. Один из них - это то, что называется реализацией метода, а другой - тип объекта во время выполнения.

object.GetType() реализуется в object и он всегда будет возвращать тип времени выполнения экземпляра, к которому он обращен.

Теперь, когда вы вызываете метод Foo из любого данного класса, который не реализует Foo а скорее наследует его от базового типа (ваш случай), base.Foo или же Foo по сути одно и то же, потому что единственный существующий Foo является base.Foo,

Однако, если класс реализует свой собственный Foo поспорим, что он перекрывает виртуальный метод или скрывает не виртуальный метод, вызываемый метод будет другим. Не смущайтесь другими ответами, утверждающими, что поведение, которое вы видите, связано с GetType не быть виртуальным, это не правда.

class A { int Foo() => 1;}
class B { }
class C { new int Foo() => 2; }

призвание Foo или же base.Foo изнутри B то же самое, называя это изнутри C не является; бывший вернется 2 последний 1,

GetType() всегда возвращает текущий тип, даже если вызван на base, Чтобы получить базовый тип, вы можете сделать это:

class A
{
    public override int GetHashCode()
    {
        Console.WriteLine(this.GetType().BaseType.Name);
        return 0;
    }
}

КСТАТИ base.GetHashCode() работает как положено. Если вы позвоните в течение A он выполнит object реализация.

Коментарий Equalsk и его пост ( здесь для краткости) - это то, что вам нужно знать, но я сделаю дополнительный шаг и расскажу вам, почему вы так хотите.

Дано class A наследуется только от System.ObjectИ учитывая class B а также class C подклассы class A:

В классе B или C, base.GetType().Name будет А. Вы ожидали этого, потому что это определено в подклассах, которые они наследуют от А.

В классе А вы все еще получаете А. Почему бы вам не захотеть object?

Ответ прост. Скажем, я пишу такой метод:

public static void DoStuff(A input)
{
}

Я могу отправить DoStuff(input) с input классы А, В или С. Это потому, что их base тип А. Это желательно. Мы не хотели бы неявно (и запутанно) исключать класс A из метода, который берет его производные; если бы мы это сделали, мы бы хотели, чтобы A был непостижимым интерфейсом.

Думать о System.Object как предок. Если кто-то спрашивает вас, откуда вы, вы не отвечаете "Эволюция в Месопотамии", вы, как правило, просто обращаетесь к линии, имеющей отношение к вашему существованию. object Класс по сути является первичным тиском, поэтому вы не будете ссылаться на него, если не попытаетесь что-то сказать, он должен принять все, что передано в качестве параметра, или не знаете, с каким типом объекта вы будете иметь дело.

Пример этого последнего случая:

public void DoStuffAgain(object x)
{
        Messagebox.Show(x.GetType().Name);
}

В теории все, что происходит по трубе, будет object, Вместо этого вы можете пройти этот класс "А" и захотите узнать "А", потому что это то, что вы прошли. Это верно, хотя х имеет тип object,

BaseType (свойство) вернет вашу базу для класса, как указано в других ответах. Это не приведет вас к objectОднако, если класс явно не наследует от чего-то другого.

Другие вопросы по тегам