Created
September 18, 2019 06:10
-
-
Save gkinsman/ed48848c65e027c12fac05ff2d882e11 to your computer and use it in GitHub Desktop.
C# Result type
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IResult | |
{ | |
bool WasSuccessful { get; } | |
string[] Errors { get; } | |
bool WasFailure { get; } | |
} | |
public class Result : IResult | |
{ | |
private string[] _errors; | |
private Result() | |
{ | |
} | |
public bool WasSuccessful { get; private set; } | |
public bool WasFailure | |
{ | |
get { return !WasSuccessful; } | |
} | |
public string[] Errors | |
{ | |
get { return _errors.ToArray(); } | |
} | |
public string ErrorString | |
{ | |
get { return string.Join(Environment.NewLine, _errors); } | |
} | |
public static Result Failed(params string[] errors) | |
{ | |
return new Result() { _errors = errors.ToArray() }; | |
} | |
public static Result Failed(params IResult[] becauseOf) | |
{ | |
return new Result() { _errors = becauseOf.SelectMany(b => b.Errors).ToArray() }; | |
} | |
public static Result Success() | |
{ | |
return new Result() { WasSuccessful = true }; | |
} | |
public static Result From(params Result[] results) | |
{ | |
var failed = results.Where(r => !r.WasSuccessful).ToArray(); | |
if (failed.Length == 0) return Result.Success(); | |
return Result.Failed(failed.SelectMany(f => f.Errors).ToArray()); | |
} | |
} | |
public class Result<T> : IResult | |
{ | |
private T _value; | |
private string[] _errors; | |
private Result() | |
{ | |
} | |
public bool WasSuccessful { get; private set; } | |
public string[] Errors | |
{ | |
get { return _errors != null ? _errors.ToArray() : null; } | |
} | |
public string ErrorString | |
{ | |
get { return _errors != null ? string.Join(Environment.NewLine, _errors) : null; } | |
} | |
public T Value | |
{ | |
get | |
{ | |
if (!WasSuccessful) throw new Exception("No value as the operation was not successful"); | |
return _value; | |
} | |
} | |
public bool WasFailure | |
{ | |
get { return !WasSuccessful; } | |
} | |
public static Result<T> Failed() | |
{ | |
return new Result<T>() { _errors = new string[0] }; | |
} | |
public static Result<T> Failed(params string[] errors) | |
{ | |
return new Result<T>() { _errors = errors.ToArray() }; | |
} | |
public static Result<T> Failed(params IResult[] becauseOf) | |
{ | |
return new Result<T>() { _errors = becauseOf.SelectMany(b => b.Errors).ToArray() }; | |
} | |
public static Result<T> Success(T value) | |
{ | |
return new Result<T>() { WasSuccessful = true, _value = value }; | |
} | |
public static implicit operator Result<T>(T value) | |
{ | |
return Success(value); | |
} | |
public static implicit operator T(Result<T> result) | |
{ | |
return result.Value; | |
} | |
public T ValueOr(T def) | |
{ | |
return WasSuccessful ? Value : def; | |
} | |
public override string ToString() | |
{ | |
return WasSuccessful ? "" + Value : ErrorString; | |
} | |
public static Result<T> From<TIn>(Result<TIn> result) where TIn : T | |
{ | |
return result.WasSuccessful ? Success(result.Value) : Failed(result); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment