Question

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.

Was it helpful?

Solution

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");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top