Last active
April 18, 2018 18:35
-
-
Save Keboo/021fdef8f641b7cf89c1db9338a1b47d to your computer and use it in GitHub Desktop.
A simple result implementation using the null object pattern.
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 class Service | |
{ | |
public Result<Person> FindPerson(string query) | |
{ | |
try | |
{ | |
Person person = ...; | |
return person ?? Result.NotFound<Person>(); //Not strictly neccisary; the implicit operator will do a null check. | |
} | |
catch (Exception e) | |
{ | |
//Do stuff with the exception | |
return Result.Exception<Person>(e); | |
} | |
} | |
} | |
public class Person | |
{ | |
public string FirstName { get; set; } | |
public string LastName { get; set; } | |
} |
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 static class Result | |
{ | |
public static Result<T> NotFound<T>(string message = null) where T : class => | |
new Result<T>(new NotFoundError(message)); | |
public static Result<T> Exception<T>(Exception exception, string message = null) where T : class => | |
new Result<T>(new ExceptionError(exception, message)); | |
} |
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 IResultError | |
{ | |
string Message { get; } | |
} | |
public class NotFoundError : IResultError | |
{ | |
public string Message { get; } | |
public NotFoundError(string message = null) | |
{ | |
Message = message ?? "Item not found"; | |
} | |
} | |
public class ExceptionError : IResultError | |
{ | |
public ExceptionError(Exception exception, string message = null) | |
{ | |
Exception = exception; | |
Message = message ?? exception.Message; | |
} | |
public Exception Exception { get; } | |
public string Message { get; } | |
} |
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 struct Result<T> where T : class | |
{ | |
public T Item { get; } | |
private readonly IReadOnlyList<IResultError> _Errors; | |
public IReadOnlyList<IResultError> Errors => _Errors ?? Array.Empty<IResultError>(); | |
public bool IsSuccess { get; } | |
private Result(T item) | |
{ | |
Item = item; | |
IsSuccess = true; | |
_Errors = Array.Empty<IResultError>(); | |
} | |
public Result(params IResultError[] errors) | |
{ | |
if (errors?.Any() != true) throw new ArgumentException("At least one error is required", nameof(errors)); | |
_Errors = errors; | |
Item = default; | |
IsSuccess = false; | |
} | |
public T GetItemOrDefault(T @default = default) => IsSuccess ? Item : @default; | |
public static implicit operator Result<T>(T item) => item != default(T) ? new Result<T>(item) : Result.NotFound<T>(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment