I've had a look around the cecil questions here and I haven't seen anything regarding this particular question.
What I am trying to achieve is find a variable in method.Body.Variables
that is of a certain type (System.Exception
in my case)
I wrote the following code thinking it would do the trick:
var exceptionTypeReference = module.Import(typeof(Exception));
var exceptionVariable = method.Body.Variables.First(x => x.VariableType == exceptionTypeReference);
What seems strange to me even though I am sure the reason is my noobness with cecil is that I get a "Sequence contains no matching elements" error at runtime.
I've stepped through the code and I know there is a variable there and that it's type is System.Exception
, but it does not want to match up with exceptionTypeReference
.
I'm certain that this is simple and that my brain is fried from learning cecil. Even so, any pointers, smacks across the face with a wet fish, etc., would be much appreciated.
Each time you import a type it is a different instance of TypeReference
So this
var typeReference1 = moduleDefinition.Import(typeof (Exception));
var typeReference2 = moduleDefinition.Import(typeof (Exception));
Debug.WriteLine(typeReference1 == typeReference2);
Will output false
.
So when you are doing the query
VariableType
may be an instance of TypeReference
representing Exception
exceptionTypeReference
will be an instance of TypeReference
representing Exception
But they are not the same reference and there is no built in equality checking on TypeReference
.
What you need to do is
var exceptionType = module.Import(typeof(Exception));
var exceptionVariable = method
.Body
.Variables
.First(x => x.VariableType.FullName == exceptionType.FullName);
Also remember you have to handle inherited exception types.
As a side not be careful using .Import(typeof (Exception))
. The reason is that it give you the Exception type of the current code, not the Exception type of the target assembly. For example you could be processing a WinRT assembly using a .net4 assembly. Importing the .net4 Exception type will probably give you some strange behavior.
So you are just as safe doing this
var exceptionVariable = method
.Body
.Variables
.First(x => x.VariableType.FullName == "System.Exception");