PsemError." /> PsemError." /> PsemError." />
Record
public record Result<T> : System.ValueType, System.IEquatable<SharpMeter.Core.Result<T>>

Namespace: SharpMeter.Core

Discriminated union representing either a success value or a PsemError.

Type Parameters

NameConstraintsDescription
TThe success value type.

Inheritance

Inherits from: System.ValueType

Implements: System.IEquatable<SharpMeter.Core.Result<T>>

Properties

NameDescription
Error Gets the error. Throws if the result is a success.
IsFailure Gets a value indicating whether this result represents failure.
IsSuccess Gets a value indicating whether this result represents success.
Value Gets the success value. Throws if the result is a failure.

Error

PsemError Result<T>.Error { get; }

Gets the error. Throws if the result is a success.

Exceptions

ExceptionCondition
!:InvalidOperationExceptionThe result is a success.

IsFailure

bool Result<T>.IsFailure { get; }

Gets a value indicating whether this result represents failure.

IsSuccess

bool Result<T>.IsSuccess { get; }

Gets a value indicating whether this result represents success.

Value

T Result<T>.Value { get; }

Gets the success value. Throws if the result is a failure.

Exceptions

ExceptionCondition
!:InvalidOperationExceptionThe result is a failure.

Methods

NameDescription
Bind(Result<TNew>> bind) Flat maps the success value using the specified function.
Failure(PsemError error) static Creates a failed result containing the specified error.
FromError(PsemError error) static Named alternate for the implicit conversion from PsemError to Result`1.
Map(Func<T, TNew> map) Maps the success value using the specified function.
Match(Func<T, TResult> onSuccess, PsemError, TResult> onFailure) Pattern matches on the result, invoking the appropriate function.
Success(T value) static Creates a successful result containing the specified value.
ToResult(T value) static Named alternate for the implicit conversion from T to Result`1.
ToString() override

Bind(Result> bind)

Result<TNew> Result<T>.Bind<TNew>(Func<T, Result<TNew>> bind)

Flat maps the success value using the specified function.

Failure(PsemError error)

Result<T> Result<T>.Failure(PsemError error)

Creates a failed result containing the specified error.

FromError(PsemError error)

Result<T> Result<T>.FromError(PsemError error)

Named alternate for the implicit conversion from PsemError to Result`1.

Map(Func map)

Result<TNew> Result<T>.Map<TNew>(Func<T, TNew> map)

Maps the success value using the specified function.

Match(Func onSuccess, PsemError, TResult> onFailure)

TResult Result<T>.Match<TResult>(Func<T, TResult> onSuccess, Func<PsemError, TResult> onFailure)

Pattern matches on the result, invoking the appropriate function.

Success(T value)

Result<T> Result<T>.Success(T value)

Creates a successful result containing the specified value.

ToResult(T value)

Result<T> Result<T>.ToResult(T value)

Named alternate for the implicit conversion from T to Result`1.

Operators

NameDescription
op_Implicit(T value) static Implicitly converts a value to a successful result.
op_Implicit(PsemError error) static Implicitly converts a PsemError to a failed result.

op_Implicit(T value)

Result<T>.implicit operator Result<T>(T value)

Implicitly converts a value to a successful result.

op_Implicit(PsemError error)

Result<T>.implicit operator Result<T>(PsemError error)

Implicitly converts a PsemError to a failed result.

Type Relationships
classDiagram
                    style Result fill:#f9f,stroke:#333,stroke-width:2px
                    Result --|> ValueType : inherits
                    Result ..|> Result~T~~ : implements
                
View Source
/// <summary>
///     Discriminated union representing either a success value or a <see cref = "PsemError"/>.
/// </summary>
/// <typeparam name = "T">The success value type.</typeparam>
[SuppressMessage("Design", "CA1000:Do not declare static members on generic types", Justification = "Success/Failure factory methods are the standard pattern for Result types.")]
public readonly record struct Result<T>
{
#region Fields
    private readonly T? _value;
    private readonly PsemError? _error;
#endregion
#region Properties
    /// <summary>Gets a value indicating whether this result represents success.</summary>
    public bool IsSuccess { get; }
    /// <summary>Gets a value indicating whether this result represents failure.</summary>
    public bool IsFailure => !IsSuccess;
    /// <summary>Gets the success value. Throws if the result is a failure.</summary>
    /// <exception cref = "InvalidOperationException">The result is a failure.</exception>
    public T Value => IsSuccess ? _value! : throw new InvalidOperationException($"Cannot access Value on a failed result: {_error}");
    /// <summary>Gets the error. Throws if the result is a success.</summary>
    /// <exception cref = "InvalidOperationException">The result is a success.</exception>
    public PsemError Error => IsFailure ? _error!.Value : throw new InvalidOperationException("Cannot access Error on a successful result.");

#endregion
#region Constructors
    private Result(T value)
    {
        _value = value;
        _error = null;
        IsSuccess = true;
    }

    private Result(PsemError error)
    {
        _value = default;
        _error = error;
        IsSuccess = false;
    }

#endregion
#region Factory Methods
    /// <summary>Creates a successful result containing the specified value.</summary>
    public static Result<T> Success(T value) => new(value);
    /// <summary>Creates a failed result containing the specified error.</summary>
    public static Result<T> Failure(PsemError error) => new(error);
#endregion
#region Operators
    /// <summary>Implicitly converts a value to a successful result.</summary>
    public static implicit operator Result<T>(T value) => Success(value);
    /// <summary>Implicitly converts a <see cref = "PsemError"/> to a failed result.</summary>
    public static implicit operator Result<T>(PsemError error) => Failure(error);
    /// <summary>Named alternate for the implicit conversion from <typeparamref name = "T"/> to <see cref = "Result{T}"/>.</summary>
    public static Result<T> ToResult(T value) => Success(value);
    /// <summary>Named alternate for the implicit conversion from <see cref = "PsemError"/> to <see cref = "Result{T}"/>.</summary>
    public static Result<T> FromError(PsemError error) => Failure(error);
#endregion
#region Methods
    /// <summary>Pattern matches on the result, invoking the appropriate function.</summary>
    public TResult Match<TResult>(Func<T, TResult> onSuccess, Func<PsemError, TResult> onFailure)
    {
        ArgumentNullException.ThrowIfNull(onSuccess);
        ArgumentNullException.ThrowIfNull(onFailure);
        return IsSuccess ? onSuccess(_value!) : onFailure(_error!.Value);
    }

    /// <summary>Maps the success value using the specified function.</summary>
    public Result<TNew> Map<TNew>(Func<T, TNew> map)
    {
        ArgumentNullException.ThrowIfNull(map);
        return IsSuccess ? Result<TNew>.Success(map(_value!)) : Result<TNew>.Failure(_error!.Value);
    }

    /// <summary>Flat maps the success value using the specified function.</summary>
    public Result<TNew> Bind<TNew>(Func<T, Result<TNew>> bind)
    {
        ArgumentNullException.ThrowIfNull(bind);
        return IsSuccess ? bind(_value!) : Result<TNew>.Failure(_error!.Value);
    }

    /// <inheritdoc/>
    public override string ToString() => IsSuccess ? $"Success({_value})" : $"Failure({_error})";
#endregion
}
Was this page helpful?