【问题标题】:FxCOp Custom RulesFxCOp 自定义规则
【发布时间】:2023-05-21 10:35:01
【问题描述】:

我一直在研究 FxCOP 自定义规则。我正在努力使用 IL 指令行。我有一个基本的疑问,当我们实现 c# 代码时,我们得到操作码,这些操作码是否在每条指令的不同行中(源代码指令在一行中有多个操作码)

现在,我的导师要求我计算使用了多个操作码的不同行。但是,我的理解是,每条 IL 指令都在不同的行中。我将尝试显示以下意见的差异:

源代码

opcode 1, opcode 2, opcode 3
opcode 4, opcode 5

My Opinion                   My Mentor's Opinion

Opcode 1                     Opcode 1,Opcode 2, Opcode 3
Opcode 2                     Opcode 5, Opcode 6
opcode 3

我无法找到哪个是真的。请帮助我找出对于任何给定的 c# 代码,IL 指令是否在单独的行中,尽管指令在源代码的同一行中,或者如果这是我的导师所相信的并且有一种方法可以找到不同的行。

谢谢

【问题讨论】:

  • 我不明白你在问什么。一条 C# 源代码行可以由 0...n 个 IL 操作码表示。该行可以被编译器删除(所以 0 个操作码),或者它可以是 x 个操作码
  • 是的,我们可以得到总的操作码计数,同意。但是我们能知道每行源代码中使用了多少操作码吗?我想,我们不能……但我想确认一下。
  • IL 没有“线条”。您需要 PDB 文件将 IL 操作码映射回源代码行。最简单的方法是使用 ildasm.exe 的 /linenum 选项。请注意,您是在浪费时间,Roslyn 是未来,今天就在这里。
  • 帮助:) 谢谢

标签: c# fxcop


【解决方案1】:

你可以这样写:

public override ProblemCollection Check(Member member)
{
    Method method = member as Method;

    if (method == null)
    {
        return base.Check(member);
    }

    Console.WriteLine("Method: {0}", member.Name);

    InstructionCollection ops = method.Instructions;

    foreach (Instruction op in ops)
    {
        Console.WriteLine("File: {0}, Line: {1}, Pos: {2}, OpCode: {3}", op.SourceContext.FileName, op.SourceContext.StartLine, op.SourceContext.StartColumn, op.OpCode);
    }

    Console.WriteLine();

    return base.Problems;
}

请注意,在发布模式下,代码行和操作码之间的关系有点“随机”,因为 C# 编译器可以重新排列一些代码。在 Debug 模式下,关系更加清晰。

注意 (2) 我只考虑StartLineStartColumn。有EndLineEndColumn 属性。

【讨论】:

  • 结束行和结束列属性的使用方式类似吗?
  • @shivangikulshrestha 是的。它们是数字。我还没有测试过它们如何处理像 if (...) { ... some lines ... } else { ... some other lines } 这样的块指令
  • 是的 xanatos,只要稍微改变逻辑,我就可以根据需要使用上述概念。谢谢 :) 他们在块指令方面也工作得很好。