Skip to main content

Result API Reference

The complete surface of Result and Result<TValue> from UnambitiousFx.Functional. For concepts and worked examples, see the Result guide.

Core types

public readonly partial record struct Result : IResult;

public readonly partial record struct Result<TValue> : IResult
where TValue : notnull;

TValue is constrained to notnull. Both types are immutable value types.

Factory methods

Each Success/Ok and Failure/Fail pair below are aliases. Generic overloads (<T>) produce a Result<T>; non-generic overloads produce a Result.

MethodSignatureDescription
Success / OkResult Success()A success with no value.
Success / OkResult<T> Success<T>(T value)A success carrying value.
Failure / FailResult Failure(string message)Failure from a message (wrapped in ExceptionalFailure).
Failure / FailResult Failure(Exception error)Failure wrapping an exception.
Failure / FailResult Failure(Failure failure)Failure from a Failure object.
Failure / FailResult Failure(params IEnumerable<Failure> errors)Failure merging many into an AggregateFailure.
Failure / FailResult<T> Failure<T>(...)Generic forms of the four overloads above.

Static failure factories

Extension factories that attach a semantic Code and structured metadata. Each has a non-generic (Result) and generic (Result<T>) overload.

MethodSignatureFailure type / code
FailNotFoundResult<T> FailNotFound<T>(string resource, string identifier, string? messageOverride = null)NotFoundFailureNOT_FOUND
FailValidationResult<T> FailValidation<T>(string message)ValidationFailureVALIDATION
FailUnauthenticatedResult<T> FailUnauthenticated<T>(string? reason)UnauthenticatedFailureUNAUTHENTICATED
FailUnauthorizedResult<T> FailUnauthorized<T>(string? reason)UnauthorizedFailureUNAUTHORIZED
FailConflictResult<T> FailConflict<T>(string message)ConflictFailureCONFLICT
FailBadRequestResult<T> FailBadRequest<T>(string message)BadRequestFailureBAD_REQUEST

Inspection

MemberSignatureDescription
IsSuccessbool IsSuccess { get; }True when the operation succeeded.
IsFailurebool IsFailure { get; }True when the operation failed.
MetadataIReadOnlyMetadata Metadata { get; }Contextual metadata attached to the result.
TryGetValuebool TryGetValue(out TValue? value)Extracts the value on success (Result<T> only).
TryGetFailurebool TryGetFailure(out Failure? error)Extracts the failure on failure.
TryGetbool TryGet(out TValue? value, out Failure? error)Extracts both at once (Result<T> only).
Deconstructvoid Deconstruct(out TValue? value, out Failure? error)Tuple deconstruction.
ToResultResult ToResult()Drops the value, keeping state + metadata (Result<T> only).

Matching

MethodSignatureDescription
MatchTOut Match<TOut>(Func<TValue, TOut> success, Func<Failure, TOut> failure)Collapse both branches to a value.
Matchvoid Match(Action<TValue> success, Action<Failure> failure)Side-effecting match.
Switchvoid Switch(Action<TValue> success, Action<Failure> failure)Alias for the action-based Match.
IfSuccessvoid IfSuccess(Action<TValue> action)Run an action only on success.
IfFailurevoid IfFailure(Action<Failure> action)Run an action only on failure.

For the non-generic Result, the success delegate takes no argument (e.g. Match(Func<TOut> onSuccess, Func<Failure, TOut> onFailure)).

Transformation

MethodSignatureDescription
MapResult<TOut> Map<TValue, TOut>(this Result<TValue>, Func<TValue, TOut> map)Transform the value with a plain function.
BindResult<TOut> Bind<TOut>(this Result<TValue>, Func<TValue, Result<TOut>> bind)Chain another result-returning step.
ThenResult<TValue> Then(this Result<TValue>, Func<TValue, Result<TValue>> then)Follow-up step preserving the value type.
ThenResult<TValue> Then(this Result<TValue>, Func<TValue, Result> then)Follow-up check that keeps the original value.
ThenResult Then(this Result, Func<Result> func)Sequence two non-generic results.
FlattenResult<TValue> Flatten<TValue>(this Result<Result<TValue>>)Collapse one level of nesting.

Failure handling

MethodSignatureDescription
EnsureResult<TValue> Ensure<TValue>(this Result<TValue>, Func<TValue, bool> predicate, Func<TValue, Failure> errorFactory)Fail when the predicate is false.
RecoverResult<TValue> Recover(this Result<TValue>, Func<Failure, TValue> recoverFunc)Turn a failure into a success via a factory.
RecoverResult<TValue> Recover(this Result<TValue>, TValue fallback)Turn a failure into a success via a fallback value.
CompensateResult<TValue> Compensate<TValue>(this Result<TValue>, Func<Failure, Result> rollback)Run a rollback on failure; merges both failures if the rollback fails.
CompensateResult Compensate(this Result, Func<Failure, Result> rollback)Non-generic compensation.
TryResult<TOut> Try<TValue, TOut>(this Result<TValue>, Func<TValue, TOut> func)Run a throwing function, catching exceptions into a failure.
TryResult Try(this Result, Action action)Run a throwing action, catching exceptions into a failure.

Side effects

MethodSignatureDescription
TapResult<TValue> Tap(this Result<TValue>, Action<TValue> tap)Observe the value on success; returns the result unchanged.
TapResult<TValue> Tap(this Result<TValue>, Action tap)Observe success without the value.
TapIfResult<TValue> TapIf(this Result<TValue>, Func<TValue, bool> predicate, Action<TValue> tap)Observe only when success and predicate hold.
TapFailureResult<TValue> TapFailure(this Result<TValue>, Action<Failure> tap)Observe the failure on the failure track.

Tap, TapIf, and TapFailure also exist on the non-generic Result.

Extraction

MethodSignatureDescription
ValueOrTValue ValueOr(this Result<TValue>, TValue fallback)Value, or a fallback on failure.
ValueOrTValue ValueOr(this Result<TValue>, Func<TValue> fallbackFactory)Value, or a lazily-produced fallback.
ValueOrDefaultTValue? ValueOrDefault(this Result<TValue>)Value, or default(TValue) on failure.
ValueOrThrowTValue ValueOrThrow(this Result<TValue>)Value, or throws the aggregated exception.
ValueOrThrowTValue ValueOrThrow(this Result<TValue>, Func<Failure, Exception> exceptionFactory)Value, or throws a custom exception.

Metadata

MethodSignatureDescription
WithMetadataResult<TValue> WithMetadata(string key, object? value)Add a single key/value pair.
WithMetadataResult<TValue> WithMetadata(params (string Key, object? Value)[] items)Add several pairs.
WithMetadataResult<TValue> WithMetadata(IReadOnlyMetadata metadata)Merge an existing metadata bag.
WithMetadataResult<TValue> WithMetadata(IEnumerable<KeyValuePair<string, object?>> metadata)Merge key/value pairs.
WithMetadataResult<TValue> WithMetadata(Action<MetadataBuilder> configure)Configure via a builder.

All WithMetadata overloads also exist on the non-generic Result.

LINQ

MethodSignatureDescription
SelectResult<TOut> Select<TIn, TOut>(this Result<TIn>, Func<TIn, TOut> selector)Query-syntax Map.
SelectManyResult<TOut> SelectMany<TIn, TOut>(this Result<TIn>, Func<TIn, Result<TOut>> binder)Query-syntax Bind.
SelectManyResult<TOut> SelectMany<TIn, TCollection, TOut>(this Result<TIn>, Func<TIn, Result<TCollection>> binder, Func<TIn, TCollection, TOut> projector)from … from … select form.
WhereResult<TValue> Where<TValue>(this Result<TValue>, Func<TValue, bool> predicate)Filter; produces a ValidationFailure when false.
CombineResult Combine(this IEnumerable<Result>)Succeeds only if all succeed; aggregates all failures.
CombineResult<IEnumerable<TValue>> Combine<TValue>(this IEnumerable<Result<TValue>>)Collect all values, or aggregate all failures.

Implicit conversions

ConversionDirection
Result<TValue>(TValue value)value → success
Result<TValue>(Failure failure)failure → failed Result<TValue>
Result(Failure failure)failure → failed Result

Async overloads

Most operators have Task<Result<T>> and ValueTask<Result<T>> extension overloads — including Map, Bind, Then, Flatten, Match, Switch, Ensure, Recover, Compensate, Try, Tap / TapFailure, ValueOr*, Combine, and the LINQ operators. They accept both synchronous and asynchronous continuations, so a single awaited chain can freely mix Map(x => …) with Bind(x => …Async(x)):

Result<Receipt> receipt = await LoadCartAsync(cartId)
.Bind(cart => ReserveStockAsync(cart))
.Map(reservation => new Receipt(reservation.Id));

See also