我正在使用LINQ表达式树生成动态代码。
在该代码中,我需要将一些BlockExpression
包裹到using
语句中,如下所示:
using(GetLock()) {
return ...SomeExpr...;
}
没有Expression.Using
,我不确定如何为Expression.TryFinally
正确创建变量
答案 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;
}