27

Is anyone aware of any differences between typeof(T) where T : struct, for example, vs. t.GetType() where t is a System.Object?
ILdasm shows that typeof(T) uses System.Type::GetTypeFromHandle(RuntimeTypeHandle handle), and the other is just plain System.Object::GetType(). The implementations are [MethodImpl(MethodImplOptions.InternalCall)], so the methods are defined in native code in the CLR. So, I'm just wondering if anyone is aware of any reason to prefer one over the other?

EDIT: Let me clarify, I'm mostly interested in the cases where it doesn't seem to matter which you choose - that is, is there a performance difference, or any other reason? Thanks!

Richard Anthony Hein
  • 10,550
  • 3
  • 42
  • 62
  • 2
    If you know statically (at compile-time) what type you want, use typeof. Otherwise, use GetType() to get it at run-time. – Eldritch Conundrum Jul 05 '13 at 19:12
  • I figured that the perf of typeof(T) would be better than Object.GetType(), but really, it is probably totally insignificant. – Richard Anthony Hein Jul 05 '13 at 19:22
  • possible duplicate of [Type Checking: typeof, GetType, or is?](http://stackoverflow.com/questions/983030/type-checking-typeof-gettype-or-is) – Amicable Jul 05 '13 at 19:24
  • 1
    I suspect that Object::GetType() just does a Type::GetTypeFromHandle after it finds the RuntimeTypeHandle in the instance of t. So, typeof may be a tiny bit faster. If you are interested in the performance, you should benchmark it. But for readability/maintainability I think it is better to stick to typeof when you can use it. – Eldritch Conundrum Jul 05 '13 at 19:27
  • @Amicable Yes, saw all those, I should have put performance in the question title, because that's not addressed by the suggested duplicate. – Richard Anthony Hein Jul 05 '13 at 19:29
  • @EldritchConundrum Thanks, that's sort of what I was thinking but things go native, so it's tough to say. I should have asked if anyone has some benchmarks handy on typeof vs. GetType() where everything else is equal. I've flagged this question for deletion because it's really just become a duplicate. – Richard Anthony Hein Jul 05 '13 at 19:36
  • So what is your **actual problem**? [What types of questions should I avoid asking? - You should only ask practical, answerable questions based on actual problems that you face.](http://stackoverflow.com/help/dont-ask) – Erik Philips Jul 05 '13 at 19:37
  • @ErikPhilips Actual problem is to determine any performance differences to improve performance of my code. If you want to close it as a duplicate, point to http://stackoverflow.com/a/6417977/1149773 instead of http://stackoverflow.com/questions/983030/type-checking-typeof-gettype-or-is. – Richard Anthony Hein Jul 05 '13 at 19:44
  • 2
    Actually, from the duplicates, the answer seems to be, "go benchmark it", or "nobody knows or cares". ;) – Richard Anthony Hein Jul 05 '13 at 19:47
  • @RichardHein: Actually, there are some benchmarks by Jon Skeet. I've posted a link below. – Douglas Jul 05 '13 at 19:50
  • @RichardHein there is no code provided to attempt a solution, so this appears to be preemptive optimization. – Erik Philips Jul 05 '13 at 20:06
  • @ErikPhilips The code is var t = typeof(T); vs. var t = t.GetType(), and I provided the IL. I already voted to close it myself, so as I said, vote to close if you think it really needs more code, but I wouldn't agree with your reasoning that code has to be provided. Some questions don't require code as questions or answers and I'm pretty sure that's not a requirement of SO. – Richard Anthony Hein Jul 05 '13 at 20:23
  • Ok, the real answer is here, thanks @Douglas: http://stackoverflow.com/a/353435/1149773 We can now close this as a duplicate and point to that or whatever. – Richard Anthony Hein Jul 05 '13 at 20:27

4 Answers4

52

typeof is used when you want to get the Type instance representing a specific type. GetType gives the runtime type of the object on which it is called, which may be different from the declared type.

For example:

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"
    }
}

In the above case, within the Main method, you're dealing with instances of type A; thus, if you care about the declared type, you would use typeof(A). However, the CreateA method actually returns an instance of a derived class, B, despite declaring the base class as the return type. If you want to find out about this runtime type, call GetType on the returned instance.

Edit: Mehrdad's comment points in the right direction. Although typeof emits a GetTypeFromHandle call that takes a RuntimeTypeHandle as parameter, the said parameter would actually correspond to the specific type whose metadata token is on the evaluation stack. In some instances, this token would be there implicitly (due to the current method invocation); otherwise, it can be pushed there explicitly by calling ldtoken. You can see more examples of this in these answers:

Edit2: If you're looking for performance benchmarks, you can refer to Jon Skeet's answer. His results were (for 100 million iterations):

typeof(Test):   2756ms
test.GetType(): 3734ms
erics12357
  • 49
  • 1
  • 9
Douglas
  • 53,759
  • 13
  • 140
  • 188
4

Well, sometimes in generic code, you know the compile time type from a type parameter T, without having an instance. Then you must use typeof(T).

At other times, typically in non generic code, you might be interested in the runtime type of an object. Then you use GetType().

So in some cases, depending on what you want to know, or what you can query for, you only have one option.

And sometimes, you could choose.

3

You use typeof when you want compile-time information and GetType when you want runtime information.

If you're in a situation where you can use either, you should use typeof because it can be resolved at compile-time. This makes it clearer what the Type value will be and (in principle) allows more optimizations.

The typeof keyword takes a compile-time type identifier and gives you the corresponding runtime instance of Type:

Type intType = typeof(int);
Type stringType = typeof(string);
Type objectType = typeof(object);
Type genericType = typeof(T);

// not permitted: typeof(1), typeof(someVariable)

The GetType instance method takes a run-time instance and tells you its exact runtime type:

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()

You typically only need to use typeof or GetType when writing something that does reflection, creating expression trees by hand, or using the terrible Enum methods (which take an instance of Type instead of a generic type parameter).

Craig Gidney
  • 17,763
  • 5
  • 68
  • 136
2

GetType() is used to retrieve the instance type which actually you have but typeof() used to get an instance type what you don't have also GetType() gets resolved at runtime, while typeof() is resolved at compile time.

Alyafey
  • 1,455
  • 3
  • 15
  • 23
  • 2
    `typeof()` is **not** resolved at compile time, it results in a method call. – MarioDS Aug 25 '15 at 20:27
  • @MDeSchaepmeester is right: typeof() is resolved to a method call. `Type.GetTypeFromHandle(RuntimeTypeHandle handle)`. -1 – T-moty May 02 '16 at 15:58