2

我在这里查看了 cecil 问题,但没有看到任何关于这个特定问题的信息。

我想要实现的是找到method.Body.Variables一个特定类型的变量(System.Exception在我的情况下)

我编写了以下代码,认为它可以解决问题:

var exceptionTypeReference = module.Import(typeof(Exception));
var exceptionVariable = method.Body.Variables.First(x => x.VariableType == exceptionTypeReference);

尽管我确信原因是我对 cecil 的菜鸟是我在运行时收到“序列不包含匹配元素”错误,但对我来说似乎很奇怪。

我已经浏览了代码,我知道那里有一个变量,它的类型是System.Exception,但它不想与exceptionTypeReference.

我确信这很简单,而且我的大脑因学习 cecil 而被炸毁。即便如此,任何指针,用湿鱼打脸等,将不胜感激。

4

1 回答 1

4

每次导入类型时,它都是一个不同的实例TypeReference

所以这

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

会输出false

因此,当您进行查询时

  • VariableType可能是TypeReference表示的一个实例Exception
  • exceptionTypeReference将是TypeReference表示的一个实例Exception

但是它们不是同一个引用,并且没有内置的相等检查TypeReference

你需要做的是

var exceptionType = module.Import(typeof(Exception));
var exceptionVariable = method
              .Body
              .Variables
              .First(x => x.VariableType.FullName == exceptionType.FullName);

另请记住,您必须处理继承的异常类型。

作为一方不小心使用.Import(typeof (Exception))。原因是它为您提供了当前代码的异常类型,而不是目标程序集的异常类型。例如,您可以使用 .net4 程序集处理 WinRT 程序集。导入 .net4 Exception 类型可能会给你一些奇怪的行为。

所以你这样做是安全的

var exceptionVariable = method
                   .Body
                   .Variables
                   .First(x => x.VariableType.FullName == "System.Exception");
于 2013-01-05T09:57:24.933 回答