在LINQ表达式中使用语句

时间:2019-01-22 01:51:10

标签: c# linq-expressions

我正在使用LINQ表达式树生成动态代码。

在该代码中,我需要将一些BlockExpression包裹到using语句中,如下所示:

using(GetLock()) {
  return ...SomeExpr...;
}

没有Expression.Using,我不确定如何为Expression.TryFinally正确创建变量

1 个答案:

答案 0 :(得分:1)

您需要创建类似

的代码
IDisposable disposable;
try
{
  disposable = GetLock();
  // rest of using block
}
finally
{
  if (disposable != null)
    disposable.Dispose();
}

下一个方法将创建该表达式

private static Expression<Action> CreateExpression<T>(Expression<Func<T>> getLock) where T : IDisposable
{
    var disposableType = typeof(IDisposable);
    var dispose = disposableType.GetMethod("Dispose");
    if (dispose == null)
        throw new InvalidOperationException();

    var disposable = Expression.Variable(disposableType, "disposable");
    var tryFinally = Expression.TryFinally(
        Expression.Block(
            Expression.Assign(disposable, Expression.Convert(Expression.Invoke(getLock), disposableType))
            // rest of using block
        ),
        Expression.IfThen(
            Expression.NotEqual(disposable, Expression.Constant(null)),
            Expression.Call(disposable, dispose)
        )
    );

    var lambda = Expression.Lambda<Action>(
      Expression.Block(
        new []{disposable}, // variable
        tryFinally // body
      )
    );

    return lambda;
}