IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

April (2018)

(1 item)

August (2014)

(1 item)

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

Getting a MethodInfo From a Method Token

Wednesday 31 August, 2005, 10:51 PM

The typeof operator in C# generates code that returns a Type object. It does this in a way that is much more direct than an 'equivalent' call to Type.GetType. (I'm ignoring the overload that takes no parameters by the way. That's special.) You pass a string to Type.GetType and at runtime it attempts to locate the type object represented by that string. The call to Type.GetType can fail at runtime, throwing an exception when the string cannot be resolved to a Type object.

Compare this to how typeof works. It uses a completely different approach: the IL ldtoken instruction. The IL for a typical typeof looks like this:

ldtoken SomeClass
call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)

where SomeClass is the name of the class. Of course the class name isn't what gets written out as the opcode parameter. If we look at the definition of ldtoken we see that in the compiled IL (i.e. the binary) its parameter is a metadata token. In this case it'll be either a typedef or a typeref.

That metadata token essentially identifies a row in either the type definition or type reference metadata table. By the time the JIT compiler has generated the executable code for the method that contains the ldtoken it will have resolved that metadata token into a reference to the type. If the type cannot be located, JIT compilation of the method will fail. (And that would only happen if something is rather bizarrely wrong in your deployment.) So you are guaranteed that if you actually get as far as executing a typeof expression, it is guaranteed to succeed. Compare this to Type.GetType, which definitely can fail. For example, this code:

Type.GetType("System.Srting")

will JIT compile just fine, but will fail at runtime, because there's no such type. The C# compiler won't even let you compile the 'equivalent' typeof.

So I get a relatively warm fuzzy feeling about using typeof - I like code that will only be able to run if it can't fail. All other things being equal, I prefer this to code that has potential runtime failure modes.

I've always been mildly perplexed that there's no equivalent way of retrieving a MethodInfo object. E.g. a hypothetical methodinfo(SomeClass.SomeMethod) operator. It's not up the top of my list of language features I want added, it just seems mildly inconsistent to have the operator for getting Type objects but not the corresponding FieldInfo and MethodInfo objects. (Interestingly, there doesn't seem to be a direct way to retrieve an EventInfo in IL, so I can't really object to that one not being in the language.)

Until recently, I had never looked into the details of this. I wasn't previously sure if this missing feature was just something C# chooses not to do, or whether it's because, it can't be done. But I recently had reason to generate some IL that does exacly this, so I can now say with confidence that it's possible, and it's just that C# doesn't supply a corresponding operator.

It took me a while to get it right, hence this blog entry. I went down a blind alley for some time trying to use ldftn. You use that when initializing a delegate. I just assumed that the opcode means "load function token", but was getting no joy trying to use this in conjunction with MethodBase.GetMethod. I eventually realised that ldftn is the wrong thing - that actually loads what is effectively a function pointer, not a metadata token. To load the metadata token for a method, you actually use the same opcode as you do for loading a class token. So the IL for the MethodInfo equivalent of typeof looks like this:

ldtoken method void SomeClass::SomeMethod()
call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)

...which seems kind of obvious now I look at it. Still, I hope I this might save someone else from going down the blind alley of using ldftn when it should be ldtoken.

Copyright © 2002-2024, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk