Table of Contents

Class Result

Namespace
Trellis
Assembly
Trellis.Core.dll

Static factory and helper methods for constructing Result<TValue> values.

public static class Result
Inheritance
Result
Inherited Members

Remarks

No-payload outcomes are represented as Result<TValue>. Call Ok() / Fail(Error) / Ensure(bool, Error) / Try(Action, Func<Exception, Error>?) for no-payload outcomes; call Ok<TValue>(TValue) / Fail<TValue>(Error) / Try<T>(Func<T>, Func<Exception, Error>?) for value-bearing outcomes.

default(Result<Unit>) represents a failure carrying a sentinel Error.Unexpected with ReasonCode = "default_initialized" — uninitialized state is a typed failure, never a silent success. Always construct via Ok(); analyzer TRLS019 flags explicit default(Result<Unit>) at call sites.

Methods

Combine<T1, T2>(Result<T1>, Result<T2>)

Combines two independent Result<TValue> instances into a single tuple result.

public static Result<(T1, T2)> Combine<T1, T2>(Result<T1> r1, Result<T2> r2)

Parameters

r1 Result<T1>

First result.

r2 Result<T2>

Second result.

Returns

Result<(T1, T2)>

A success result with a 2-element tuple if both succeed; otherwise a failure with combined errors.

Type Parameters

T1

Type of the first result value.

T2

Type of the second result value.

Examples

var emailResult = EmailAddress.TryCreate(dto.Email);
var nameResult = FirstName.TryCreate(dto.Name);

var result = Result.Combine(emailResult, nameResult)
    .Bind((email, name) => User.Create(email, name));

Ensure(bool, Error)

Returns a successful no-payload result if flag is true; otherwise a failure with the specified error.

public static Result<Unit> Ensure(bool flag, Error error)

Parameters

flag bool

The condition to assert. true yields success; false yields failure.

error Error

The error to wrap when flag is false. Always evaluated by the caller.

Returns

Result<Unit>

Ok() when flag is true; otherwise Fail(Error).

Examples

Authorization guard inside IAuthorizeResource<TResource>.Authorize:

public IResult Authorize(Actor actor, Order resource) =>
    Result.Ensure(
        resource.OwnerId == actor.UserId,
        new Error.Forbidden("order_not_owned"));

Domain invariant guard inside an aggregate method (replaces a hand-written if/return):

public Result<Unit> Cancel(DateTimeOffset now) =>
    Result.Ensure(Status == OrderStatus.Pending,
        new Error.Conflict(null, "order_not_cancellable") { Detail = "Only pending orders can be cancelled." })
    .Tap(() => { Status = OrderStatus.Cancelled; CancelledAt = now; });

Remarks

Canonical guard primitive. Prefer Result.Ensure(condition, error) over hand-written if (!condition) return Result.Fail(error); blocks or ad-hoc ternaries — Ensure reads as a single declarative line, participates in Activity tracing, and is the preferred form for guard clauses in current guidance.

For an asynchronous predicate use EnsureAsync(Func<Task<bool>>, Error). For a value-threaded guard that preserves an existing Result<TValue> on success, use the Result<TValue>.Ensure(predicate, error) extension overloads on EnsureExtensions.

Ensure(Func<bool>, Error)

Returns a successful no-payload result if the predicate is true; otherwise a failure with the specified error.

public static Result<Unit> Ensure(Func<bool> predicate, Error error)

Parameters

predicate Func<bool>
error Error

Returns

Result<Unit>

EnsureAsync(Func<Task<bool>>, Error)

Asynchronously evaluates the predicate and returns success if true; otherwise a failure with the specified error.

public static Task<Result<Unit>> EnsureAsync(Func<Task<bool>> predicate, Error error)

Parameters

predicate Func<Task<bool>>
error Error

Returns

Task<Result<Unit>>

Fail(Error)

Creates a failed no-payload result (Result<Unit>) with the specified error.

public static Result<Unit> Fail(Error error)

Parameters

error Error

Returns

Result<Unit>

Fail<TValue>(Error)

Creates a failed result with the specified error.

public static Result<TValue> Fail<TValue>(Error error)

Parameters

error Error

Returns

Result<TValue>

Type Parameters

TValue

Ok()

Creates a successful no-payload result (Result<Unit>).

public static Result<Unit> Ok()

Returns

Result<Unit>

Remarks

Goes through the constructor so that Current receives the success status, matching the tracing behavior of Ok<TValue>(TValue). Always prefer this factory over default(Result<Unit>): default represents failure with the Error.Unexpected sentinel, not success.

Ok<TValue>(TValue)

Creates a successful result wrapping the provided value.

public static Result<TValue> Ok<TValue>(TValue value)

Parameters

value TValue

Returns

Result<TValue>

Type Parameters

TValue

Try(Action, Func<Exception, Error>?)

Executes the action and converts exceptions to a failed no-payload result using the optional mapper.

public static Result<Unit> Try(Action work, Func<Exception, Error>? map = null)

Parameters

work Action
map Func<Exception, Error>

Returns

Result<Unit>

TryAsync(Func<Task>, Func<Exception, Error>?)

Executes the asynchronous action and converts exceptions to a failed no-payload result.

public static Task<Result<Unit>> TryAsync(Func<Task> work, Func<Exception, Error>? map = null)

Parameters

work Func<Task>
map Func<Exception, Error>

Returns

Task<Result<Unit>>

TryAsync<T>(Func<Task<T>>, Func<Exception, Error>?)

Executes the asynchronous function and converts exceptions to a failed result.

public static Task<Result<T>> TryAsync<T>(Func<Task<T>> func, Func<Exception, Error>? map = null)

Parameters

func Func<Task<T>>
map Func<Exception, Error>

Returns

Task<Result<T>>

Type Parameters

T

Try<T>(Func<T>, Func<Exception, Error>?)

Executes the function and converts exceptions to a failed result using the optional mapper (default Unexpected).

public static Result<T> Try<T>(Func<T> func, Func<Exception, Error>? map = null)

Parameters

func Func<T>
map Func<Exception, Error>

Returns

Result<T>

Type Parameters

T