use<R extends Object?, T extends Object?> function

R use<R extends Object?, T extends Object?>(
  1. T value,
  2. R block(
    1. T value
    ), {
  3. void dispose(
    1. T value
    )?,
})

Executes a block with a value and ensures cleanup via disposal.

This implements the resource management pattern (similar to try-with-resources in Java). The block function is called with value, and dispose is is called in a finally block, regardless of whether the block succeeds or throws.

Use this for:

  • File/stream handling
  • Database connection management
  • Cleanup of temporary resources
  • Any resource with a defined lifecycle

Parameters:

  • value: The resource to use
  • block: Function that uses the resource and returns a result
  • dispose: Optional cleanup function called in finally

If both block and dispose throw, the exception from dispose replaces the exception from block, as with a Dart finally clause.

Example:

final content = use(
  File('data.txt'),
  (file) => file.readAsStringSync(),
  dispose: (file) => print('File closed'),
);

Implementation

R use<R extends Object?, T extends Object?>(
  T value,
  R Function(T value) block, {
  void Function(T value)? dispose,
}) {
  try {
    return block(value);
  } finally {
    dispose?.call(value);
  }
}