Skip to content

Instantly share code, notes, and snippets.

@dburriss
Last active August 28, 2018 21:41
Show Gist options
  • Select an option

  • Save dburriss/de32bb8df1bbe9bf549b3bb0c60a8f68 to your computer and use it in GitHub Desktop.

Select an option

Save dburriss/de32bb8df1bbe9bf549b3bb0c60a8f68 to your computer and use it in GitHub Desktop.
A safeish `Result` type. It throws if `IsSuccess` has not been called before accessing `Value`.
using System;
using System.Collections.Generic;
using System.Linq;
namespace X
{
public class Result
{
public static Result Success() => new Result();
public static Result Fail(params Exception[] exceptions) => new Result(exceptions);
private List<Exception> errors = new List<Exception>();
private Result()
{ }
private Result(Exception[] exceptions)
{
errors.AddRange(exceptions);
}
public bool IsSuccess { get { return !errors.Any(); } }
public IEnumerable<Exception> Errors => errors;
}
public class Result<T>
{
public static Result<T> Success(T value) => new Result<T>(value);
public static Result<T> Fail(params Exception[] exceptions) => new Result<T>(exceptions);
private T value;
private List<Exception> errors = new List<Exception>();
private Result(T value)
{
this.value = value;
}
private Result(Exception[] exceptions)
{
errors.AddRange(exceptions);
}
private bool iHaveBeenChecked = false;
public T Value
{
get
{
if (iHaveBeenChecked == false)
{
if (errors.Any())
{
throw new InvalidOperationException(
$"You cannot access {nameof(Value)} without checking {nameof(IsSuccess)}.",
new AggregateException($"You cannot access {nameof(Value)} Since you have multiple errors.", errors)
);
}
throw new InvalidOperationException($"You cannot access {nameof(Value)} without checking {nameof(IsSuccess)}.");
}
return value;
}
}
public bool IsSuccess
{
get
{
iHaveBeenChecked = true;
return !errors.Any();
}
}
public IEnumerable<Exception> Errors => errors;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment