Skip to content

Commit 5f2657f

Browse files
author
Jakab László
committed
Chain extension
1 parent f0f25d1 commit 5f2657f

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using AutSoft.Linq.Expressions.ExpressionVisitors;
2+
3+
using System.Linq.Expressions;
4+
5+
namespace AutSoft.Linq.Expressions;
6+
7+
/// <summary>
8+
/// Extension methods for <see cref="Expression{T}"/> with extended functionality for chaining
9+
/// </summary>
10+
public static class ChainExtension
11+
{
12+
/// <summary>
13+
/// Chaining together two <see cref="Expression{T}"/>
14+
/// </summary>
15+
/// <typeparam name="TIn">Type of input paramter of the result <see cref="Expression{T}"/>'s function</typeparam>
16+
/// <typeparam name="TInterstitial">Type of interstitial parameter of the <see cref="Expression{T}"/> function</typeparam>
17+
/// <typeparam name="TOut">Type of output paramter of the result <see cref="Expression{T}"/>'s function</typeparam>
18+
/// <param name="incomingChainLink">The incoming <see cref="Expression{T}"/> to chaning</param>
19+
/// <param name="outgoingChainLink">The outgoing <see cref="Expression{T}"/> to chaning</param>
20+
/// <returns>The chained together <see cref="Expression{T}"/></returns>
21+
public static Expression<Func<TIn, TOut>> Chain<TIn, TInterstitial, TOut>(
22+
this Expression<Func<TIn, TInterstitial>> incomingChainLink,
23+
Expression<Func<TInterstitial, TOut>> outgoingChainLink)
24+
{
25+
var visitor = new SwapVisitor(outgoingChainLink.Parameters[0], incomingChainLink.Body);
26+
return Expression.Lambda<Func<TIn, TOut>>(visitor.Visit(outgoingChainLink.Body), incomingChainLink.Parameters);
27+
}
28+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System.Linq.Expressions;
2+
3+
namespace AutSoft.Linq.Expressions.ExpressionVisitors;
4+
5+
/// <summary>
6+
/// An <see cref="ExpressionVisitor"/>, which swap the visited <see cref="Expression"/> to an other
7+
/// </summary>
8+
public class SwapVisitor : ExpressionVisitor
9+
{
10+
private readonly Expression _source;
11+
private readonly Expression _replacement;
12+
13+
/// <summary>
14+
/// Initializes a new instance of the <see cref="SwapVisitor"/> class.
15+
/// </summary>
16+
/// <param name="source">The <see cref="Expression"/>, with which identical ones must be replaced</param>
17+
/// <param name="replacement">The <see cref="Expression"/>, for which the matches must be exchanged</param>
18+
public SwapVisitor(Expression source, Expression replacement)
19+
{
20+
_source = source;
21+
_replacement = replacement;
22+
}
23+
24+
/// <summary>
25+
/// Visit the <see cref="Expression"/>
26+
/// </summary>
27+
/// <param name="node">The <see cref="Expression"/>, that we visit</param>
28+
/// <returns>The <see cref="Expression"/> after the visit</returns>
29+
public override Expression? Visit(Expression? node)
30+
{
31+
return node == _source ? _replacement : base.Visit(node);
32+
}
33+
}

0 commit comments

Comments
 (0)