typeof общий и приведенный тип

Допустим, у нас есть общий метод:

public void GenericMethod<T>(T item)
{
    var typeOf = typeof(T);
    var getType = item.GetType();
}

И мы вызываем его со следующими параметрами:

GenericMethod(1)
GenericMethod((object) 1)

Результаты:

typeOf = System.Int32
getType = System.Int32

а также

typeOf = System.Object
getType = System.Int32

Может кто-нибудь объяснить мне, почему typeof integer, приведенный к объекту, возвращает System.Object, но .GetType() возвращает System.Int32?

Ответ 1

typeof возвращает статический (во время компиляции) тип универсального параметра T

GetType возвращает динамический (во время выполнения) тип значения, содержащегося в item переменной.


Разницу легче увидеть, если вы сделаете свой метод неуниверсальным. Предположим, что B является подтипом A:

public void NonGenericMethod(A item)
{
    var typeOf = typeof(A);
    var getType = item.GetType();
}

В этом случае вызов NonGenericMethod(new B()) даст

A
B

Рекомендуется для дальнейшего чтения:


Теперь вы можете спросить: почему вы использовали NonGenericMethod(A item) в вашем примере вместо NonGenericMethod(B item)? Это очень хороший вопрос! Рассмотрим следующий (не универсальный) пример кода:

public static void NonGenericMethod(A item)
{
    Console.WriteLine("Method A");
    var typeOf = typeof(A);
    var getType = item.GetType();
}
public static void NonGenericMethod(B item)
{
    Console.WriteLine("Method B");
    var typeOf = typeof(B);
    var getType = item.GetType();
}

Что вы получаете, когда вызываете NonGenericMethod((A) new B()) (что аналогично аргументу (object) 1 в вашем примере)?

Method A
A
B

Зачем? Потому что разрешение перегрузки выполняется во время компиляции, а не во время выполнения. Во время компиляции тип выражения (A) new B() - это A, точно так же, как тип времени (object) 1 время компиляции - это object.

Рекомендуется для дальнейшего чтения:

Ответ 2

В GenericMethod((object) 1) T будет object. typeof отражает это.

Но item.GetType(); является виртуальным методом и будет выполняться во время выполнения в Int32.

Ответ 3

Вызов GetType разрешается во время выполнения, тогда как typeof разрешается во время компиляции. Вот почему это дает разные результаты. Вы можете проверить здесь - Когда и где использовать GetType() или typeof()?

Ответ 4

Это говорит мне, что Typeof дает вам тип времени компиляции, тогда как GetType дает вам точный тип времени выполнения.

Ответ 5

Многое проясняется, когда вы пропускаете вмешательство типа:

GenericMethod(1) на самом деле является GenericMethod<int>(1).

GenericMethod((object) 1) выводится как GenericMethod<object>((object) 1).

Когда вы спрашиваете typeof(T), он возвращает T вы указали в вызове метода. Вы также можете сделать GenericMethod<object>("a"), который будет возвращать object по typeof(T).

GetType возвращает фактический тип времени выполнения предоставленного экземпляра.