Using
UsingExpression represents a using statement that acquires an IDisposable resource, executes a body, and guarantees disposal in a try/finally block regardless of exceptions. It is equivalent to:
using ( var resource = disposable )
body;
Factory Methods
using static Hyperbee.Expressions.ExpressionExtensions;
| Overload | Description |
|---|---|
Using( ParameterExpression variable, Expression disposable, Expression body ) | Named variable, disposable expression, and body |
Using( Expression disposable, Expression body ) | Anonymous disposable – no variable binding |
Usage
Dispose a Resource
using static System.Linq.Expressions.Expression;
using static Hyperbee.Expressions.ExpressionExtensions;
// Equivalent to: using (var conn = new SqlConnection(connString)) { ... }
var conn = Variable( typeof(SqlConnection), "conn" );
var usingExpr = Using(
conn,
New( typeof(SqlConnection).GetConstructor([typeof(string)])!, Constant( connectionString ) ),
Call( conn, typeof(SqlConnection).GetMethod("Open")! )
);
var lambda = Lambda<Action>( usingExpr );
var fn = lambda.Compile();
fn(); // connection is opened and then disposed
Anonymous Using (No Variable)
// When you don't need to reference the resource inside the body
var usingExpr = Using(
New( typeof(MyResource).GetConstructor(Type.EmptyTypes)! ), // disposable
Call( typeof(Console).GetMethod("WriteLine", [typeof(string)])!, Constant( "working" ) )
);
Nested Using
var outer = Variable( typeof(OuterResource), "outer" );
var inner = Variable( typeof(InnerResource), "inner" );
var usingExpr = Using(
outer,
New( typeof(OuterResource).GetConstructor(Type.EmptyTypes)! ),
Using(
inner,
Call( outer, typeof(OuterResource).GetMethod("CreateInner")! ),
Call( inner, typeof(InnerResource).GetMethod("Execute")! )
)
);
Inside an Async Block
var reader = Variable( typeof(StreamReader), "reader" );
var asyncBlock = BlockAsync(
[reader],
Using(
reader,
New( typeof(StreamReader).GetConstructor([typeof(string)])!, Constant( "data.txt" ) ),
Await( Call( reader, typeof(StreamReader).GetMethod("ReadToEndAsync") ) )
)
);
Notes
- Disposal is guaranteed even if the body throws an exception (wrapped in
try/finally). - If
disposableevaluates tonull, no exception is thrown – null is checked before callingDispose(). - The
variableparameter (when provided) is bound to the value ofdisposableand is accessible insidebody. It must match the type ofdisposable. - Both
IDisposableandIAsyncDisposableare supported.