简体   繁体   English

如何使用mono.cecil按类型在方法体中找到变量?

[英]How can I find a variable in a method body by type using mono.cecil?

I've had a look around the cecil questions here and I haven't seen anything regarding this particular question.我在这里查看了 cecil 问题,但没有看到有关此特定问题的任何内容。

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)我想要实现的是在method.Body.Variables中找到一个特定类型的变量(在我的例子中是System.Exception

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.尽管我确信原因是我对 cecil 的不熟悉,但对我来说似乎很奇怪的是我在运行时收到“序列不包含匹配元素”错误。

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 .我已经逐步完成了代码,我知道那里有一个变量,它的类型是System.Exception ,但它不想与exceptionTypeReference匹配。

I'm certain that this is simple and that my brain is fried from learning cecil.我确信这很简单,而且我的大脑是从学习 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每次导入类型时,它都是TypeReference的不同实例

So this所以这

var typeReference1 = moduleDefinition.Import(typeof (Exception));
var typeReference2 = moduleDefinition.Import(typeof (Exception));
Debug.WriteLine(typeReference1 == typeReference2);

Will output false .将输出false

So when you are doing the query所以当你做查询时

  • VariableType may be an instance of TypeReference representing Exception VariableType可能是代表ExceptionTypeReference的实例
  • exceptionTypeReference will be an instance of TypeReference representing Exception exceptionTypeReference将是代表ExceptionTypeReference一个实例

But they are not the same reference and there is no built in equality checking on TypeReference .但它们不是相同的引用,并且没有对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)) .一方面不要小心使用.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.原因是它为您提供了当前代码的 Exception 类型,而不是目标程序集的 Exception 类型。 For example you could be processing a WinRT assembly using a .net4 assembly.例如,您可以使用 .net4 程序集处理 WinRT 程序集。 Importing the .net4 Exception type will probably give you some strange behavior.导入 .net4 Exception 类型可能会给您带来一些奇怪的行为。

So you are just as safe doing this所以你这样做也很安全

var exceptionVariable = method
                   .Body
                   .Variables
                   .First(x => x.VariableType.FullName == "System.Exception");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM