代码之家  ›  专栏  ›  技术社区  ›  LOST

在Linq表达式中使用语句

  •  0
  • LOST  · 技术社区  · 5 年前

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

    在代码中,我需要包装一些 BlockExpression 变成一个 using 如下声明:

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

    没有 Expression.Using ,我不知道如何正确地为 Expression.TryFinally

    1 回复  |  直到 5 年前
        1
  •  1
  •   Aleks Andreev Md. Suman Kabir    5 年前

    您需要创建看起来像

    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;
    }