This represents the Try (or Exceptional) monad.
The Try monad allows for defining a chain of lazily executed operations that are executed sequentially.
In case of exceptions, the next appropriate (i. e. assignment compatible) catch handler will be invoked.
The whole Try
construction and execution is primarily regarded an expression, this means every catch-handler
must return a value.
Try<int> tryResult = Try
.Do(_SomeMethod)
.Then(_SomeOtherMethodThatThrows)
.Then(_AndAnotherMethod) // assuming _AndAnotherMethod() returns an int
.Catch<InvalidOperationException>(ex =>
{
Log.WriteError("Operation did not succeed");
return -99;
});
The constructed tryResult
will not be executed until Execute()
is invoked on it.
int result = tryResult.Execute();
If no apropriate catch-handler is found, execution of the Try
throws:
var result = Try
.Do<int>(() => throw new ArithmeticException())
.Catch<InvalidOperationException>(ex =>
{
Log.WriteError("Operation did not succeed");
return -99;
})
.Execute(); // throws an ArithmeticException
Execution of an empty Try<T>
or TryAsync<T>
leads to default(T)
:
var result = default(Try<string>).Execute();
// result is default(string)
There is an async
variant for all construction and binding methods.
var result = await Try
.DoAsync(_SomeAsyncMethod)
.ThenAsync(_SomeOtherAsyncMethodThatThrows)
.ThenAsync(_AndAnotherAsyncMethod)
.CatchAsync<InvalidOperationException>(async ex =>
{
Log.WriteError("Operation did not succeed");
return -99;
})
.ExecuteAsync();
The explicit calls to .Execute()
and .ExecuteAsync()
can be 'replaced' by an await
because
both Try`1
and AsyncTry`1
are awaitables:
var result = await Try
.DoAsync(_SomeAsyncMethod)
.ThenAsync(_SomeOtherAsyncMethodThatThrows)
.ThenAsync(_AndAnotherAsyncMethod)
.CatchAsync<InvalidOperationException>(async ex =>
{
Log.WriteError("Operation did not succeed");
return -99;
});
All .Catch<T>(..)
and .CatchAsync<T>(..)
variants also provide overloads that allow for specifying
the exception type as Type
object.
var result = await Try
.DoAsync(_SomeAsyncMethod)
.CatchAsync(
typeof(InvalidOperationException),
async ex =>
{
Log.WriteError("Operation did not succeed");
return -99;
});