Class TapExtensions
- Namespace
- Trellis
- Assembly
- Trellis.Core.dll
Provides extension methods for executing side effects on successful Results without changing the Result.
public static class TapExtensions
- Inheritance
-
TapExtensions
- Inherited Members
Examples
var result = GetUser(id)
.Tap(user => _logger.LogInformation("Found user: {Name}", user.Name))
.Bind(user => ValidateUser(user))
.Tap(() => _metrics.IncrementCounter("user.validated"));
// Without cancellation token
var result = EmailAddress.TryCreate("user@example.com")
.Combine(UserId.TryCreate("123"))
.Tap((email, userId) => _logger.LogInformation("Processing user {UserId} with email {Email}", userId, email))
.Tap((email, userId) => _metrics.RecordUserCreation())
.Bind((email, userId) => CreateUser(email, userId));
// With cancellation token (closure capture)
var ct = cancellationToken;
var result = await EmailAddress.TryCreate("user@example.com")
.Combine(UserId.TryCreate("123"))
.TapAsync((email, userId) => LogAsync(email, userId, ct))
.BindAsync((email, userId) => CreateUserAsync(email, userId, ct));
Remarks
Tap is useful for performing side effects (like logging, auditing, or debugging) in a functional pipeline without breaking the chain. The action is only executed if the Result is successful, and the original Result is always returned unchanged. This allows you to "peek" at values flowing through the pipeline.
Methods
Tap<TValue>(Result<TValue>, Action)
Executes the given action if the result is a success. Returns the original result unchanged.
public static Result<TValue> Tap<TValue>(this Result<TValue> result, Action action)
Parameters
resultResult<TValue>The result to tap.
actionActionThe action to execute if the result is successful.
Returns
- Result<TValue>
The original result unchanged.
Type Parameters
TValueType of the result value.
Tap<TValue>(Result<TValue>, Action<TValue>)
Executes the given action with the value if the result is a success. Returns the original result unchanged.
public static Result<TValue> Tap<TValue>(this Result<TValue> result, Action<TValue> action)
Parameters
resultResult<TValue>The result to tap.
actionAction<TValue>The action to execute with the value if the result is successful.
Returns
- Result<TValue>
The original result unchanged.
Type Parameters
TValueType of the result value.
Tap<T1, T2>(Result<(T1, T2)>, Action<T1, T2>)
Executes a side effect action on a successful 2-element tuple result without modifying the result.
public static Result<(T1, T2)> Tap<T1, T2>(this Result<(T1, T2)> result, Action<T1, T2> action)
Parameters
resultResult<(T1, T2)>The result containing a 2-element tuple.
actionAction<T1, T2>The side effect action to execute on the tuple elements if successful.
Returns
- Result<(T1, T2)>
The original result unchanged.
Type Parameters
T1The type of element 1 in the tuple.
T2The type of element 2 in the tuple.
Examples
var result = FirstName.TryCreate("John")
.Combine(LastName.TryCreate("Doe"))
.Tap((arg1, arg2) => _logger.LogInfo($"Values: {arg1 + ", " + arg2}"))
.Bind((arg1, arg2) => ProcessData(arg1, arg2));
Remarks
If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.
Tap<T1, T2, T3>(Result<(T1, T2, T3)>, Action<T1, T2, T3>)
Executes a side effect action on a successful 3-element tuple result without modifying the result.
public static Result<(T1, T2, T3)> Tap<T1, T2, T3>(this Result<(T1, T2, T3)> result, Action<T1, T2, T3> action)
Parameters
resultResult<(T1, T2, T3)>The result containing a 3-element tuple.
actionAction<T1, T2, T3>The side effect action to execute on the tuple elements if successful.
Returns
- Result<(T1, T2, T3)>
The original result unchanged.
Type Parameters
T1The type of element 1 in the tuple.
T2The type of element 2 in the tuple.
T3The type of element 3 in the tuple.
Examples
var result = FirstName.TryCreate("John")
.Combine(LastName.TryCreate("Doe"))
.Combine(Field3.TryCreate("value3"))
.Tap((arg1, arg2, arg3) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3}"))
.Bind((arg1, arg2, arg3) => ProcessData(arg1, arg2, arg3));
Remarks
If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.
Tap<T1, T2, T3, T4>(Result<(T1, T2, T3, T4)>, Action<T1, T2, T3, T4>)
Executes a side effect action on a successful 4-element tuple result without modifying the result.
public static Result<(T1, T2, T3, T4)> Tap<T1, T2, T3, T4>(this Result<(T1, T2, T3, T4)> result, Action<T1, T2, T3, T4> action)
Parameters
resultResult<(T1, T2, T3, T4)>The result containing a 4-element tuple.
actionAction<T1, T2, T3, T4>The side effect action to execute on the tuple elements if successful.
Returns
- Result<(T1, T2, T3, T4)>
The original result unchanged.
Type Parameters
T1The type of element 1 in the tuple.
T2The type of element 2 in the tuple.
T3The type of element 3 in the tuple.
T4The type of element 4 in the tuple.
Examples
var result = FirstName.TryCreate("John")
.Combine(LastName.TryCreate("Doe"))
.Combine(Field3.TryCreate("value3"))
.Combine(Field4.TryCreate("value4"))
.Tap((arg1, arg2, arg3, arg4) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4}"))
.Bind((arg1, arg2, arg3, arg4) => ProcessData(arg1, arg2, arg3, arg4));
Remarks
If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.
Tap<T1, T2, T3, T4, T5>(Result<(T1, T2, T3, T4, T5)>, Action<T1, T2, T3, T4, T5>)
Executes a side effect action on a successful 5-element tuple result without modifying the result.
public static Result<(T1, T2, T3, T4, T5)> Tap<T1, T2, T3, T4, T5>(this Result<(T1, T2, T3, T4, T5)> result, Action<T1, T2, T3, T4, T5> action)
Parameters
resultResult<(T1, T2, T3, T4, T5)>The result containing a 5-element tuple.
actionAction<T1, T2, T3, T4, T5>The side effect action to execute on the tuple elements if successful.
Returns
- Result<(T1, T2, T3, T4, T5)>
The original result unchanged.
Type Parameters
T1The type of element 1 in the tuple.
T2The type of element 2 in the tuple.
T3The type of element 3 in the tuple.
T4The type of element 4 in the tuple.
T5The type of element 5 in the tuple.
Examples
var result = FirstName.TryCreate("John")
.Combine(LastName.TryCreate("Doe"))
.Combine(Field3.TryCreate("value3"))
.Combine(Field4.TryCreate("value4"))
.Combine(Field5.TryCreate("value5"))
.Tap((arg1, arg2, arg3, arg4, arg5) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ", " + arg5}"))
.Bind((arg1, arg2, arg3, arg4, arg5) => ProcessData(arg1, arg2, arg3, arg4, arg5));
Remarks
If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.
Tap<T1, T2, T3, T4, T5, T6>(Result<(T1, T2, T3, T4, T5, T6)>, Action<T1, T2, T3, T4, T5, T6>)
Executes a side effect action on a successful 6-element tuple result without modifying the result.
public static Result<(T1, T2, T3, T4, T5, T6)> Tap<T1, T2, T3, T4, T5, T6>(this Result<(T1, T2, T3, T4, T5, T6)> result, Action<T1, T2, T3, T4, T5, T6> action)
Parameters
resultResult<(T1, T2, T3, T4, T5, T6)>The result containing a 6-element tuple.
actionAction<T1, T2, T3, T4, T5, T6>The side effect action to execute on the tuple elements if successful.
Returns
- Result<(T1, T2, T3, T4, T5, T6)>
The original result unchanged.
Type Parameters
T1The type of element 1 in the tuple.
T2The type of element 2 in the tuple.
T3The type of element 3 in the tuple.
T4The type of element 4 in the tuple.
T5The type of element 5 in the tuple.
T6The type of element 6 in the tuple.
Examples
var result = FirstName.TryCreate("John")
.Combine(LastName.TryCreate("Doe"))
.Combine(Field3.TryCreate("value3"))
.Combine(Field4.TryCreate("value4"))
.Combine(Field5.TryCreate("value5"))
.Combine(Field6.TryCreate("value6"))
.Tap((arg1, arg2, arg3, arg4, arg5, arg6) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ", " + arg5 + ", " + arg6}"))
.Bind((arg1, arg2, arg3, arg4, arg5, arg6) => ProcessData(arg1, arg2, arg3, arg4, arg5, arg6));
Remarks
If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.
Tap<T1, T2, T3, T4, T5, T6, T7>(Result<(T1, T2, T3, T4, T5, T6, T7)>, Action<T1, T2, T3, T4, T5, T6, T7>)
Executes a side effect action on a successful 7-element tuple result without modifying the result.
public static Result<(T1, T2, T3, T4, T5, T6, T7)> Tap<T1, T2, T3, T4, T5, T6, T7>(this Result<(T1, T2, T3, T4, T5, T6, T7)> result, Action<T1, T2, T3, T4, T5, T6, T7> action)
Parameters
resultResult<(T1, T2, T3, T4, T5, T6, T7)>The result containing a 7-element tuple.
actionAction<T1, T2, T3, T4, T5, T6, T7>The side effect action to execute on the tuple elements if successful.
Returns
- Result<(T1, T2, T3, T4, T5, T6, T7)>
The original result unchanged.
Type Parameters
T1The type of element 1 in the tuple.
T2The type of element 2 in the tuple.
T3The type of element 3 in the tuple.
T4The type of element 4 in the tuple.
T5The type of element 5 in the tuple.
T6The type of element 6 in the tuple.
T7The type of element 7 in the tuple.
Examples
var result = FirstName.TryCreate("John")
.Combine(LastName.TryCreate("Doe"))
.Combine(Field3.TryCreate("value3"))
.Combine(Field4.TryCreate("value4"))
.Combine(Field5.TryCreate("value5"))
.Combine(Field6.TryCreate("value6"))
.Combine(Field7.TryCreate("value7"))
.Tap((arg1, arg2, arg3, arg4, arg5, arg6, arg7) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ", " + arg5 + ", " + arg6 + ", " + arg7}"))
.Bind((arg1, arg2, arg3, arg4, arg5, arg6, arg7) => ProcessData(arg1, arg2, arg3, arg4, arg5, arg6, arg7));
Remarks
If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.
Tap<T1, T2, T3, T4, T5, T6, T7, T8>(Result<(T1, T2, T3, T4, T5, T6, T7, T8)>, Action<T1, T2, T3, T4, T5, T6, T7, T8>)
Executes a side effect action on a successful 8-element tuple result without modifying the result.
public static Result<(T1, T2, T3, T4, T5, T6, T7, T8)> Tap<T1, T2, T3, T4, T5, T6, T7, T8>(this Result<(T1, T2, T3, T4, T5, T6, T7, T8)> result, Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
Parameters
resultResult<(T1, T2, T3, T4, T5, T6, T7, T8)>The result containing a 8-element tuple.
actionAction<T1, T2, T3, T4, T5, T6, T7, T8>The side effect action to execute on the tuple elements if successful.
Returns
- Result<(T1, T2, T3, T4, T5, T6, T7, T8)>
The original result unchanged.
Type Parameters
T1The type of element 1 in the tuple.
T2The type of element 2 in the tuple.
T3The type of element 3 in the tuple.
T4The type of element 4 in the tuple.
T5The type of element 5 in the tuple.
T6The type of element 6 in the tuple.
T7The type of element 7 in the tuple.
T8The type of element 8 in the tuple.
Examples
var result = FirstName.TryCreate("John")
.Combine(LastName.TryCreate("Doe"))
.Combine(Field3.TryCreate("value3"))
.Combine(Field4.TryCreate("value4"))
.Combine(Field5.TryCreate("value5"))
.Combine(Field6.TryCreate("value6"))
.Combine(Field7.TryCreate("value7"))
.Combine(Field8.TryCreate("value8"))
.Tap((arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ", " + arg5 + ", " + arg6 + ", " + arg7 + ", " + arg8}"))
.Bind((arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) => ProcessData(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8));
Remarks
If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.
Tap<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9)>, Action<T1, T2, T3, T4, T5, T6, T7, T8, T9>)
Executes a side effect action on a successful 9-element tuple result without modifying the result.
public static Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9)> Tap<T1, T2, T3, T4, T5, T6, T7, T8, T9>(this Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9)> result, Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action)
Parameters
resultResult<(T1, T2, T3, T4, T5, T6, T7, T8, T9)>The result containing a 9-element tuple.
actionAction<T1, T2, T3, T4, T5, T6, T7, T8, T9>The side effect action to execute on the tuple elements if successful.
Returns
- Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9)>
The original result unchanged.
Type Parameters
T1The type of element 1 in the tuple.
T2The type of element 2 in the tuple.
T3The type of element 3 in the tuple.
T4The type of element 4 in the tuple.
T5The type of element 5 in the tuple.
T6The type of element 6 in the tuple.
T7The type of element 7 in the tuple.
T8The type of element 8 in the tuple.
T9The type of element 9 in the tuple.
Examples
var result = FirstName.TryCreate("John")
.Combine(LastName.TryCreate("Doe"))
.Combine(Field3.TryCreate("value3"))
.Combine(Field4.TryCreate("value4"))
.Combine(Field5.TryCreate("value5"))
.Combine(Field6.TryCreate("value6"))
.Combine(Field7.TryCreate("value7"))
.Combine(Field8.TryCreate("value8"))
.Combine(Field9.TryCreate("value9"))
.Tap((arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ", " + arg5 + ", " + arg6 + ", " + arg7 + ", " + arg8 + ", " + arg9}"))
.Bind((arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) => ProcessData(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9));
Remarks
If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.