FluentResults
FluentResults copied to clipboard
Add Extension methods "Bind" and "Map" for IResult<T>
I tried to change my code from Result<TValue>
to IResult<TValue>
and realized, that IResult<TValue>
doesn’t have a Bind
or a Map
methods.
I think Bind
and Map
are very important features, therefore I propose adding those methods as Extensions methods.
I prepared some code changes in a fork of this project (see here: https://github.com/DrPepperBianco/FluentResults/blob/features/extensionmethods_for_interface_types/src/FluentResults/Extensions/ResultExtensions.cs).
What I did is, I added extensions methods for IResult<TValue>
and also for IResultBase
for the following methods:
-
MapErrors
-
MapSuccesses
-
Bind
-
Map
-
ToResult<TValue>
I copied those methods from the Result
class and the Result<TValue>
class.
I designed those methods, to return either IResult<TValue>
(Task<IResult<TValue>>
, ValueTask<IResult<TValue>>
resp.) or IResultBase
(Task<IResultBase>
, ValueTask<IResultBase>
resp.).
Whenever a new result is created, the IResult<TValue>
is actually a Result<TValue>
.
This has the disadvantage, that, if the input result had covariance, the output result loses this covariance. This could be circumvented with Reflection, but I am not sure, if this is a good idea.
Alternatives:
Instead of directly providing extension methods for Map
, Bind
, etc., we could just provide an extensionsMethod AsResult()
like that:
public static Result<TValue> AsResult<TValue>(this IResult<TValue> result)
{
if(result is Result<TValue> _result)
{
return _result;
}
else
{
return new Result<TValue>()
.WithValue(result.ValueOrDefault)
.WithReasons(result.Reasons):
}
}
Then you could convert an IResult to a result, before working with it.
This method assumes, that most IResults
are actually already Results
. That is of course not the case, if the result is covariant. In that case, we create a new result object. I named the method AsResult
, because in most cases it doesn't create a new object. But that is of course not true, the better name would be ToResult
, but that name is of cource already taken for another functionality.
The advantage is, we have fewer methods to maintain. The disadvantage is, that in the case of actual covariance we have create a new object, while an actual extensions method for MapErrorss
for instance, could just return the input object instead.
So what do you think?