【问题标题】:How can I find a variable in a method body by type using mono.cecil?如何使用 mono.cecil 按类型在方法主体中查找变量?
【发布时间】:2020-08-24 16:11:41
【问题描述】:

我已经查看了这里的 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 而被烧毁。即便如此,任何指点、用湿鱼打脸等,都将不胜感激。

【问题讨论】:

    标签: c# mono.cecil


    【解决方案1】:

    每次导入一个类型时,它都是 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");
    

    【讨论】:

    • 谢谢@Simon。我确实考虑过使用FullName 属性,但是(愚蠢地)认为会有更好的方法......我将使用它。我不知道您描述的异常行为。你能提供一些关于这方面的阅读材料(用于研究目的)吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 2011-06-13
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-28
    相关资源
    最近更新 更多