代码编译时方法中函数执行的计数

2024-04-16

我想计算函数“ExecuteAction”在类方法中出现的次数。

public class A : B
{
  public void X()
  {
    ExecuteAction(....);
    ExecuteAction(....);
  }
}

得分为 2,因为 ExecuteAction 出现了 2 次。我需要它,因为我构建测试框架,并希望允许外部测试操作员知道当前步骤执行的位置以及它将在哪里结束。是否可以这样做或者我应该改变我的方法?

谢谢。


下面的方法演示了如何通过反射读取方法体并统计特定方法的所有调用:

class Foo {
    public void SomeMethod() {
        ExecuteAction();
        ExecuteAction();
    }
    public void ExecuteAction() {
        //
    }
}
// --- Read the IL ---
var mInfo = typeof(Foo).GetMethod("SomeMethod");
var token = typeof(Foo).GetMethod("ExecuteAction").MetadataToken;

var methodBody = mInfo.GetMethodBody();
var rawIL = methodBody.GetILAsByteArray();

int counter = 0;
var reader = new ILReader(rawIL);
while(reader.Read(mInfo)) {
    if(reader.OpCode == OpCodes.Call && object.Equals(reader.MetadataToken, token)) {
        System.Console.WriteLine("Method \"{0}\" call detected", reader.Operand);
        counter++;
    }
}
System.Console.WriteLine("Total: {0}", counter);

The ILReader类的实现如下(此特定任务的最小实现):

class ILReader {
    readonly byte[] msil;
    int ptr;
    public ILReader(byte[] msil) {
        this.msil = msil;
    }
    public OpCode OpCode { get; private set; }
    public int MetadataToken { get; private set; }
    public object Operand { get; private set; }
    public bool Read(MethodInfo methodInfo) {
        if(ptr < msil.Length) {
            OpCode = ReadOpCode();
            Operand = ReadOperand(OpCode, methodInfo);
            return true;
        }
        return false;
    }
    OpCode ReadOpCode() {
        byte instruction = ReadByte();
        if(instruction != 254)
            return singleByteOpCode[instruction];
        else
            return doubleByteOpCode[ReadByte()];
    }
    object ReadOperand(OpCode code, MethodInfo methodInfo) {
        MetadataToken = 0;
        switch(code.OperandType) {
            case OperandType.InlineMethod:
                MetadataToken = ReadInt();
                System.Type[] methodArgs = null;
                if(methodInfo.GetType() != typeof(ConstructorInfo))
                    methodArgs = methodInfo.GetGenericArguments();
                System.Type[] typeArgs = null;
                if(methodInfo.DeclaringType != null)
                    typeArgs = methodInfo.DeclaringType.GetGenericArguments();
                return methodInfo.Module.ResolveMember(MetadataToken, typeArgs, methodArgs);
        }
        return null;
    }
    byte ReadByte() {
        return msil[ptr++];
    }
    int ReadInt() {
        byte b1 = ReadByte();
        byte b2 = ReadByte();
        byte b3 = ReadByte();
        byte b4 = ReadByte();
        return (int)b1 | (((int)b2) << 8) | (((int)b3) << 16) | (((int)b4) << 24);
    }
    #region static
    static ILReader() {
            CreateOpCodes();
        }
    static OpCode[] singleByteOpCode;
    static OpCode[] doubleByteOpCode;
    static void CreateOpCodes() {
        singleByteOpCode = new OpCode[225];
        doubleByteOpCode = new OpCode[31];

        FieldInfo[] fields = GetOpCodeFields();

        for(int i = 0; i < fields.Length; i++) {
            OpCode code = (OpCode)fields[i].GetValue(null);
            if(code.OpCodeType == OpCodeType.Nternal)
                continue;

            if(code.Size == 1)
                singleByteOpCode[code.Value] = code;
            else
                doubleByteOpCode[code.Value & 0xff] = code;
        }
    }
    static FieldInfo[] GetOpCodeFields() {
        return typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static);
    }
    #endregion static
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

代码编译时方法中函数执行的计数 的相关文章

随机推荐

  • 如何在只读 Jupyter Notebook 中保存更改

    我打开了一个 python Jupyter 笔记本 但没有注意到它处于只读 不可信模式 现在如何保存我的更改 我尝试过但没有帮助的事情 文件 gt 制作副本 文件 gt 保存并检查点 文件 gt 下载为 文件 gt 信任笔记本 如上所述he
  • MySQL 数据库中的克罗地亚变音符号 (utf-8)

    变音符号 http img98 imageshack us img98 3383 dijakritickiznakovi gif http img98 imageshack us img98 3383 dijakritickiznakovi
  • TypeScript D3 v4 导入不起作用

    我正在尝试在 D3 之上构建一个小型 JS 库来绘制折线图 我对整个场景相当陌生 但我认为跳入 深渊 是最好的学习方式 这是我的内容package json name d3play02 version 1 0 0 description m
  • 如何计算 VU 仪表刻度的对数标签?

    我使用画布编写一个仪表小部件 需要计算刻度的标签值 没问题 除非我尝试重新创建 VU 表的刻度 我知道它是对数的 但在这种类型的仪表上 这些值不是 10 的幂 see https en wikipedia org wiki VU meter
  • 将自定义 CLI 命令移动到另一个文件

    我有一些针对我正在编写的 Flask 应用程序的自定义 cli 命令 我正在按照此处的说明进行操作 命令行界面 http flask pocoo org docs 1 0 cli 问题是我不想把它们全部放在我的 app py 文件中 它会变
  • Git 配置 user.name 不起作用

    我今天安装了适用于 Windows 7 的 Git 我对 Git 还不太了解 我正在关注http git scm com book en Getting Started First Time Git Setup http git scm c
  • 模块化 pow() 中的负幂

    我们如何使用pow在模块化上下文中带有负指数 战俘 x y z 如果存在 z 则 x 和 y 必须是整数类型 并且 y 必须是非负数 gt gt gt pow 11444 357 0 0 gt gt gt pow 11444 357 487
  • 如何在 NLog 中打开和关闭特定级别的日志记录

    我在我的应用程序中使用 NLog 我想创建一个开关来打开和关闭特定的记录器级别
  • 切换 Antd 表单的可见性

    当选择下拉菜单中的选项时 我需要显示某些输入 下拉菜单包含三个选项 血压 体重和温度 当用户选择一个选项时 与该选项相关的输入字段需要可见 而其余的则需要隐藏 例如 当用户选择 血压 时 收缩压和舒张压输入字段需要可见 而温度和体重字段需要
  • 如何在 Linux 中符号链接文件? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想在Linux 中建立一个符号链接 我编写了这个 Bash 命令 其中第一个路径是我想要链接到的文件夹 第二个路径是编译的源代码 ln
  • 在 iPhone 和 Android 上生成 2D 条形码(例如 QR 码、Data Matrix、PDF417)

    我需要一个图书馆generateiPhone 和 Android 上的 2D 条形码 最好是 WM7 也可能是 j2me 其想法是将信息传输到具有相应扫描仪 解码器 的另一台设备 有哪些好的选择 ZXing http code google
  • 使用 URLField 相对于 TextField 有何优势?

    据我了解 你应该始终使用TextField当您使用 PostgreSQL 数据库时 对于可变长度字符串 因为之间的速度差异TextField and a CharField对于 PostgreSQL 来说可以忽略不计 我对 Django 比
  • API 自动化测试:有没有办法通过内容验证来自动化下载场景?

    我的应用程序中有导出到 Excel 的功能 我有一个场景 执行导出到 Excel 验证 API 响应状态和导出的 Excel 内容 使用 Postman 我可以使用 发送和下载 选项以 xlsx 格式保存导出的 Excel 稍后我可以手动验
  • 如何在 Java 中替换/删除 UTF-8 字符串中的 4(+) 字节字符?

    由于 MySQL 5 1 不支持 4 字节 UTF 8 序列 因此我需要替换 删除这些字符串中的 4 字节序列 我正在寻找一种干净的方法来替换这些字符 Apache 库用问号替换字符对于这种情况来说是可以的 当然 尽管 ASCII 等效的字
  • 与共享数据相比,消息传递的性能损失

    最近有很多关于不使用锁和使用 Erlang 等消息传递方法的讨论 或者关于使用不可变的数据结构 例如函数式编程与 C Java 中的比较 但我关心的是以下几点 AFAIK Erlang 不保证消息传递 消息可能会丢失 如果还要担心消息丢失
  • 压缩从设备获取或从库、iOS 中选择的图像

    在我的应用程序中 用户可以从设备拍摄照片或从库上传照片以将其设置为个人资料照片 现在 当用户完成后 我需要将该图像上传到服务器 通常从设备获取的图像大小为 5 6MB 我需要在上传到服务器之前将其压缩到 25KB 所以我使用以下方法 voi
  • 多标签 OneVsRestClassifier 的网格搜索?

    我正在对多标签数据进行网格搜索 如下所示 imports from sklearn svm import SVC as classifier from sklearn pipeline import Pipeline from sklear
  • Ubuntu 错误“在此 WSL 2 发行版中找不到命令‘docker’。”

    我在 Ubuntu 上运行 WSL 2 在计算机上启动和运行 docker 时遇到一些问题 我安装了 Docker Desktop 并在后台运行 并且还启用了与 Ubuntu 的 WSL 集成 当我尝试运行简单的 docker 命令时 例如
  • 在javascript中将Json时间戳转换为正常日期和时间

    我有一个 Json 时间戳 我想使用 javascript 将其转换为简单的日期时间格式 我需要以下格式的日期和时间 dd mm yyyy hr mn 这是一个示例 json 日期 我希望提取时间戳 timestamp 1326439500
  • 代码编译时方法中函数执行的计数

    我想计算函数 ExecuteAction 在类方法中出现的次数 public class A B public void X ExecuteAction ExecuteAction 得分为 2 因为 ExecuteAction 出现了 2