Skip to content

Result

Represents the result that is either a success or a failure.

It is a struct, preventing you from returning null instead.

This come in two forms:

  • without a payload - Result
  • with a payload - Result<T>

There are async version of all the extension methods.

There are extension methods that allow you to easily convert dotnet or third-party dotnet libraries to return Result.

Any method that can fail should return a Result or Result<T>

ResultError

Failures are represented as an IResultError.

These represent the context of the error.

Built-in

There are a number of built-in IResultError implementations.

You are free to create your own, by implementing either the IResultErrorNonComposite or IResultErrorComposite interfaces.

ResultErrorMessage

Represents a string error message, without any other context.

ResultErrorException

Represents a exception error.

ResultErrorEmpty

Represents an empty error message, this is mainly used internally in the library.

ResultErrorComposite

This is a special IResultError, it allows you to have a tree structure of IResultError's.

What to do with them

There are two supported ways to get the data from an IResultError:

  • GetErrorString
  • GetErrorStructure

GetErrorString

This gets a string representing the error(s). Different implementation of IResultError deal with this differently.

ResultErrorComposite will create a string of its children separating them with the specified separator.

GetErrorStructure

This gets a tree structure representing the error(s).

This tree structure is serializable to Json.

Extension Methods

Combine

Allows you to combine multiple Result's into one, if they have the same payload types.

If there is no payload on the Results passed in:

  • If all of the Results passed are success, then return a Result success
  • If any of the Results passed are failed, then return a Result failure with a ResultError of all of the failure ResultError's

If there are payloads on the Results passed in and they are all the same type:

  • If all of the Results passed are success, then return a Result success with an IEnumerable of all the Result payloads
  • If any of the Results passed are failed, then return a Result failure with a ResultError of all of the failure ResultError's

If there are IEnumerable payloads on the Results passed in and they are all the same type:

  • If all of the Results passed are success, then return a Result success with an IEnumerable of all the Result payloads concatenated together
  • If any of the Results passed are failed, then return a Result failure with a ResultError of all of the failure ResultError's

CombineAll

Allows you to combine Result's that have different payload types.

You additionally pass in a selector func.

Compensate

Allows you to provide a compensating action (that also returns a Result), if there Result is a failure.

CompensateWhen

Allows you to provide a compensating action (that also returns a Result), if there Result is a failure of a specific type and optionally matches a predicate.

CompensateWhenAny

Allows you to provide a compensating action (that also returns a Result), if there Result is a failure of a specific type and optionally matches a predicate.

Note: this will flatten and search a ResultErrorComposite.

Do - Perform side-effect only on success

Executes a side-effect if the Result is success.

DoSwitch - Perform side-effect

The DoSwitch extension methods allow you to perform a side-effect on an Result<T>.

You have to say what to do when the value is success and failure.

DoWhenFailure - Perform side-effect only on failure

Executes a side-effect if the Result is failure.

EnhanceWithError

Allows you to provide additional context to a failure.

Factory

Result.Ok and Result.Ok<T>

Creates a success Result

or

Creates a success Result<T> with the payload provided

Result.Fail

Creates a failure Result with the error provided

or

Creates a failure Result<T> with the error provided

ToResultOk - Result -> Result<T>

Creates a success Result<T> with the payload provided

FlatMap

Map - Result<T> -> Result<TR>

The Map extension methods allow you to transform an Result<T> to an Result<TR>.

The transformation will only occur if there is the Result is success.

It is assumed that the transformation func that you pass in cannot fail, i.e. throw an exception. If it can throw an exception, use then, returning a Result<TR> from the transformation func.

MapSwitch

Switch

The Switch extension methods allow you to transform an Result<T> to a TR.

You have to say what to return when the value is success and failure.

Then - Result<T> -> Result<TR>

The Then extension methods allow you to bind two Result or Result<T> methods together.

ThenSwitch

ThenTry

This can be a good way to integrate third-party libraries.

ToNonGeneric - Result.Ok<T> -> Result

The ToNonGeneric extension methods discards the payload.

Try

Will run the func wrapping it in a try / catch.

  • If an exception is thrown, it will return a Result.Fail
  • If no exception is thrown it will return a Result.Ok

This can be a good way to integrate third-party libraries.

Unwrap - Result.Ok<T> -> T or Exception

Comes out of the Result monad.

  • If the Result is Ok, then return the value if there is one
  • If the Result is Fail, then throw an exception, passing through the ResultError data

Enumerable

Choose

Filter

FlatMapAs

MapAs

Pick

PickFailureOrSuccess

ThenAs

TryToDictionary

AsyncEnumerable

Choose

Filter

MapAs

Interop with Option

Option -> Result

You can move between an Option and a Result using the 'ToResult' extension method. You just need to provide the error if the Option is not present.

Result -> Option

This is not supported as it would result in the loss of the error context.