EDIT : This question is based on the misconception that GetType() returns a string.
I'm trying to get a better handle on how C# works, so this question is more theoretical than practical.
As I understand it, calling GetType on a value type requires boxing and then calling the method. Since value types can't be inherited from, though, the type is known at compile time, so why can't the compiler simply replace the call to GetType() with a string literal?
Or is this something that could be done, but isn't considered necessary since there wouldn't be much need to call GetType on an unboxed value type anyway?
Let's consider the question you might have asked had you not had the misconception that GetType returns a string. Can the compiler compile
Foo foo = whatever;
Type t = foo.GetType();
as
Type t = typeof(Foo);
Yes, that would be a legal optimization. The compiler doesn't do that optimization because it would be a waste of the compiler team's time to do that optimization when they could be doing an optimization that actually makes a difference. Let's think about the proposed optimization.
new GetType
method on Foo
? If so, then it can do anything. The compiler team has to detect calls to the original GetType
. And then write test cases that ensure that the optimization is not applied in these cases. Foo?
instead of Foo
, so you'd have to have a special case for that in the compiler. So for all these reasons and more, the cost of the optimization is higher than the benefit it produces.
For a longer but similar discussion on how to evaluate proposed optimizations, see this answer from yesterday: Weird behaviour of c# compiler due caching delegate
In an unboxed value type, GetType
will always return the type of the variable. You already know the type of the variable, so what is the advantage to begin with? Simply use nameof
on the type if you want the name:
var i = 1;
var iKnowTheType = nameof(System.Int32); //is this evaluated at compile time?
var s = "Int32";
var areSame = ReferenceEquals(iKnowTheType, s); //returns true!
iKnowTheType
and s
are the same string, which means nameof(System.Int32)
and the literal "Int32"
are basically the same thing (read about string interning for more accurate information on this subject).
GetType
returns the runtime type of an object. In unboxed value types it will, again, always be the variable's type, but the key differnce here is that the type is evaluated at runtime:
var i = 1;
var iDontKnowTheType = i.GetType().Name;
var s = "Int32";
var areSame = ReferenceEquals(iDontKnowTheType, s); //returns false!
var areEqual = iDontKnowTheType == s; //returns true
Here, the compiler can't intern iDontKnowTheType
because that particular string
is evaluated at runtime.
GetType()
returns a Type
object. That object does not exist at compile time, only at runtime.
Also that object has lots of metadata and other runtime data attached to it, so it can be used for much more than just a 'typename comparison', just think of Reflection and Serialization.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.