在运行时生成表达式中访问异常

时间:2016-09-18 21:05:04

标签: c# exception expression-trees

很明显的情况。我用表达式做一些运行时魔术。我的单元测试会抛出一个异常,因为我正在做的事情非常复杂,因此很明显失败。

我不知道如何调试生成的委托,因此解决方法我想插入一个try-catch,将异常记录到控制台。

我只是不知道如何访问异常变量。该变量由CatchBlock - 类公开。但是我必须在工厂方法中通过身体,它超出了范围。

我该如何访问它?我没有看到任何合法的,非黑客的方式来做这件事,因为这是一个非常不寻常的话题,在互联网上找不到任何文件/信息。

到目前为止,这是我的代码:

// The actual code
BlockExpression block = Expression.Block(new[] {messageParam, objectParam},
    callExpressions.ToArray());

// The catch block around it
CatchBlock catchExpression = Expression.Catch(typeof(Exception),
    Expression.Call(typeof(Console).GetMethod(nameof(Console.WriteLine),
            BindingFlags.Public | BindingFlags.Static, null, CallingConventions.Any, new[] {typeof(string)},
            null),
        Expression.Call(// Here should be the ParameterExpression
            typeof(Exception).GetProperty(nameof(Exception.Message),
                BindingFlags.Public | BindingFlags.Instance).GetMethod)));
// The try-block for the catch
TryExpression tryExpression = Expression.TryCatch(block, catchExpression);

// Compilation ...

1 个答案:

答案 0 :(得分:1)

我拼命想解决同样的问题。我有非常相似的原因 - 动态表达式的跟踪目的。 最终解决方案就像使用different overload of Expression.Catch一样简单。

虽然 - 由于文档和示例非常稀少,很难找到。

所以如果其他人需要类似的功能 - 这里是一个非常基本的工作示例(您可以使用自定义表达式日志记录替换catch主体等):

var parExcep = Expression.Parameter(typeof (Exception), "exc");

MethodInfo excMsg = typeof(Exception).GetProperty("Message",
    BindingFlags.Public | BindingFlags.Instance).GetMethod;


TryExpression tryCatchExpr =
    Expression.TryCatch(
        Expression.Block(
            Expression.Throw(Expression.Constant(new DivideByZeroException())),
            Expression.Constant("Try block")
            ),
        Expression.Catch(
            parExcep,
            Expression.Call(parExcep, excMsg)
            )
        );

Console.WriteLine(Expression.Lambda<Func<string>>(tryCatchExpr).Compile()());

打印出来:

  

试图除以零。