用塞西尔检测封口

时间:2014-03-15 19:22:02

标签: c# cil mono.cecil

我有代码来检测何时在类似的方法中创建异常:

foreach (var instr in body.Instructions)
{
    if (instr.OpCode.Code == Code.Newobj)
    {
        var methRef = (Mono.Cecil.MethodReference)instr.Operand;
        var type = Type.GetType(methRef.DeclaringType.FullName);
        if (typeof(System.Exception).IsAssignableFrom(type))
        // do stuff
    }
}

完整代码here

到目前为止,这对于直接代码来说效果很好,但是在我处理闭包的情况下,它显然不会起作用,因为异常是在为对象生成的对象上的方法内部关闭,而不是我目前正在测试的方法。例外:

    private static  int DataAccessMethod(int value)
    {
        int r = 0;
        System.Threading.ManualResetEvent evt = new System.Threading.ManualResetEvent(false);
        var workItem = System.Threading.ThreadPool.QueueUserWorkItem((_) =>
            {
                if (r == 0)
                {
                    throw new System.InvalidOperationException("I canr spell.");
                }
                r = value * value;
                evt.Set();
            });
        evt.WaitOne();
        return r;
    }
例如

将不会被发现。我的问题是:

有没有检测到newobj的操作数是指一个闭包类型?

1 个答案:

答案 0 :(得分:3)

正如@usr在评论中指出的那样,闭包只是普通的类,它们在IL中并不明显。唯一的区别是你没有创造它;编译器为你做了。

我相信您应该查看独特的编译器生成的名称来查找它们。 EricLippert describes naming conventions followed by compiler here,请注意它在将来的编译器版本中可能会有所变化。

在得出Type是一个闭包的结论后,您可以使用CompilerGenerated属性来验证。