Result type in C#
Result type is an specialization is used in Rust for carrying
computations that can fail. It’s a sum type/enum type that
has two variants Ok
and Err
. It’s an alternative for exceptions
that don’t change the natural calling/return control flow.
Here is the class
#nullable enable
using System;
public abstract class Result<T, E>
{
Result() { }
public sealed class Ok : Result<T, E>
{
public readonly T Value;
public Ok(T ok) => Value = ok;
}
public sealed class Err : Result<T, E>
{
public readonly E Error;
public Err(E err) => Error = err;
}
public Result<T2, E> Map<T2>(Func<T, T2> func) => this switch
{
Ok _this => new Result<T2, E>.Ok(func(_this.Value)),
Err _this => new Result<T2, E>.Err(_this.Error),
_ => throw new Exception("Unreachable"),
};
public Result<T, E2> MapErr<E2>(Func<E, E2> func) => this switch
{
Err _this => new Result<T, E2>.Err(func(_this.Error)),
Ok _this => new Result<T, E2>.Ok(_this.Value),
_ => throw new Exception("Unreachable"),
};
public Result<T2, E> Bind<T2>(Func<T, Result<T2, E>> func) => this switch
{
Ok _this => func(_this.Value),
Err _this => new Result<T2, E>.Err(_this.Error),
_ => throw new Exception("Unreachable"),
};
public Result<T, E> Map(Func<T, T> func) => Map<T>(func);
public Result<T, E> MapErr(Func<T, T> func) => Map<T>(func);
public Result<T, E> Bind(Func<T, Result<T, E>> func) => Bind<T>(func);
}