Will typeof(T) == typeof(string)
where T is a generic type argument, be compiled into a constant Boolean value, since the condition is knowable at compile time?
Asked
Active
Viewed 537 times
1

Triynko
- 18,766
- 21
- 107
- 173
-
1No, it won't. Why it should compile into constant? Generic types in .NET are being constructed at run-time. – Dennis Dec 16 '15 at 07:21
-
Not so much that it should, as it could, since it would be resolvable at compile time if it was compiled like c++ templates. In that case, it certainly should compile into a constant as an optimization, but not in C# since the types retain their generic type parameters at runtime. I've done quite a bit of work with reflection and construction of generic types at runtime, but someone tried to tell me they were the same as c++ templates compiled into a separate type for each generic type used and I doubted what a knew for a minute. Just clearing things up. – Triynko Dec 17 '15 at 12:41
2 Answers
5
Generic type data exists in the IL - it is not erased like in Java. So: no, the C# compiler doesn't compile this to a constant; it compiles it the IL that talks about a generic type parameter.
The JIT on this is then reused for all reference type permutations (only each value-type permutation requires a separate JIT, for size/boxing/etc reasons). Since string
is a reference-type, this means that Foo<string>
(where typeof(T)==typeof(string)
is true
) uses the same JIT output as Foo<SomeClass>
(where typeof(T)==typeof(string)
is false
). So no: this is explicitly not a constant, even at JIT time.

Marc Gravell
- 1,026,079
- 266
- 2,566
- 2,900
-
So would this also apply the same way to a primitive type like `typeof(T) == typeof(int)`? Or would the JIT be able to optimize that to a constant? – Triynko Dec 17 '15 at 12:52
-
@Triynko that's an interesting question, and it would depend on the JIT. In theory yes: that *is* well known, because it will JIT for all value-type T, so the `typeof(T)` in the `int` case will be reducible. Whether it **does** do that, however, would require looking at the generated machine code. I do not know, basically. – Marc Gravell Dec 17 '15 at 14:15
1
I've done some performance tests on this with the following results:
- If the generic Type is a class (not a struct), there is no compiler nor runtime optimization on the statement: if (typeof(T) == typeof(someClass)).
- If the generic Type is a struct, there is compiler or runtime optimization on the if-statements of the format: if (typeof(T) == typeof(someStruct)), up to a certain point (the size of the method seems to matter: in my test-rig after 998 if-statements). After this point, performance degrades drastically: whereas these is no performance penalty for adding extra if-statements of this type before this point, an extra if-statement after this point causes a performance degradation of over 10000 %.
- Limiting the generic Type to a certain class or limit it to a struct does not change performance.
- It is the size of the method that matters, not the size of the class. Thus 10 methods may perform better than 1 large method doing the same actions.
Tested with C# on VS2017 and .net 4.6.2, with optimization turned on.

Wolfgang Grinfeld
- 870
- 10
- 11