Тип (T) против Object.GetType()
Кто-нибудь знает о каких-либо различиях между typeof(T) where T : struct
,
например, против t.GetType() where t is a System.Object
?
ILdasm показывает, что typeof (T) использует System.Type::GetTypeFromHandle(RuntimeTypeHandle handle)
, а другой просто равен t23. Реализации [MethodImpl(MethodImplOptions.InternalCall)]
,
поэтому методы определены в собственном коде в CLR. Итак, мне просто интересно, знает ли кто-нибудь о какой-либо причине, предпочитающей друг друга?
EDIT: Позвольте мне пояснить, меня больше всего интересуют случаи, когда вам кажется, что вы не выбрали - то есть, есть ли разница в производительности или какая-либо другая причина? Спасибо!
Ответы
Ответ 1
typeof
используется, когда вы хотите получить экземпляр Type
, представляющий определенный тип. GetType
предоставляет тип времени выполнения объекта, на который он вызывается, который может отличаться от объявленного типа.
Например:
class A {}
class B : A {}
class Program
{
static A CreateA()
{
return new B();
}
static void Main()
{
A a = CreateA();
Console.WriteLine(typeof(A)); // Writes "A"
Console.WriteLine(a.GetType()); // Writes "B"
}
}
В приведенном выше случае в методе Main
вы имеете дело с экземплярами типа A
; таким образом, если вы заботитесь о объявленном типе, вы должны использовать typeof(A)
. Однако метод CreateA
фактически возвращает экземпляр производного класса B
, несмотря на объявление базового класса в качестве возвращаемого типа. Если вы хотите узнать об этом типе времени выполнения, вызовите GetType
в возвращаемом экземпляре.
Изменить: Мехрдад указывает точки в правильном направлении. Хотя typeof
испускает вызов GetTypeFromHandle
, который принимает параметр RuntimeTypeHandle
as, указанный параметр будет фактически соответствовать конкретному типу, токен метаданных которого находится в стеке оценки. В некоторых случаях этот токен будет неявно (из-за текущего вызова метода); в противном случае его можно явно нажать, вызвав ldtoken. Вы можете увидеть больше примеров этого в этих ответах:
Изменить 2. Если вы ищете тесты производительности, вы можете обратиться к ответ Jon Skeet, Его результаты:
typeof(Test): 2756ms
test.GetType(): 3734ms
Ответ 2
Ну, иногда в общем коде вы знаете тип времени компиляции из параметра типа T
, не имея экземпляра. Затем вы должны использовать typeof(T)
.
В других случаях, обычно в не общем коде, вам может быть интересен тип среды выполнения. Затем вы используете GetType()
.
Поэтому в некоторых случаях, в зависимости от того, что вы хотите знать, или того, что вы можете запросить, у вас есть только один вариант.
И иногда вы можете выбирать.
Ответ 3
Вы используете typeof, когда хотите получать информацию времени компиляции и GetType, когда вам нужна информация о времени выполнения.
Если вы находитесь в ситуации, когда вы можете использовать либо, вы должны использовать typeof, потому что он может быть разрешен во время компиляции. Это дает более четкое представление о значении типа и (в принципе) позволяет больше оптимизировать.
Ключевое слово typeof использует идентификатор типа времени компиляции и предоставляет соответствующий экземпляр экземпляра Type:
Type intType = typeof(int);
Type stringType = typeof(string);
Type objectType = typeof(object);
Type genericType = typeof(T);
// not permitted: typeof(1), typeof(someVariable)
Метод экземпляра GetType принимает экземпляр времени выполнения и сообщает вам его точное время выполнения:
Type intType = 1.GetType(); // typeof(int)
Type objectType = new Object().GetType(); // typeof(object)
object x = "test";
Type stringType = x.GetType(); // typeof(string), NOT typeof(object)
// not permitted: int.GetType(), string.GetType(), T.getType()
Обычно вам нужно использовать typeof или GetType при написании чего-то, что делает отражение, создавая деревья выражений вручную или используя ужасные методы Enum (которые берут экземпляр типа вместо типового параметра типа).
Ответ 4
GetType()
используется для извлечения типа экземпляра, который на самом деле у вас есть, но typeof()
используется для получения типа экземпляра то, чего у вас нет, и GetType()
получает разрешение во время выполнения, а typeof()
разрешается при компиляции время.