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
Returns
- Result<(T1, T2)>
A success result with a 2-element tuple if both succeed; otherwise a failure with combined errors.
Type Parameters
T1Type of the first result value.
T2Type 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
flagboolThe condition to assert. true yields success; false yields failure.
errorErrorThe error to wrap when
flagis false. Always evaluated by the caller.
Returns
- Result<Unit>
Ok() when
flagis 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
Returns
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
Returns
Fail(Error)
Creates a failed no-payload result (Result<Unit>) with the specified error.
public static Result<Unit> Fail(Error error)
Parameters
errorError
Returns
Fail<TValue>(Error)
Creates a failed result with the specified error.
public static Result<TValue> Fail<TValue>(Error error)
Parameters
errorError
Returns
- Result<TValue>
Type Parameters
TValue
Ok()
Creates a successful no-payload result (Result<Unit>).
public static Result<Unit> Ok()
Returns
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
valueTValue
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
Returns
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
Returns
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
Returns
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
Returns
- Result<T>
Type Parameters
T