我有代码来检测何时在类似的方法中创建异常:
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的操作数是指一个闭包类型?
答案 0 :(得分:3)
正如@usr在评论中指出的那样,闭包只是普通的类,它们在IL中并不明显。唯一的区别是你没有创造它;编译器为你做了。
我相信您应该查看独特的编译器生成的名称来查找它们。 EricLippert describes naming conventions followed by compiler here,请注意它在将来的编译器版本中可能会有所变化。
在得出Type
是一个闭包的结论后,您可以使用CompilerGenerated
属性来验证。