diff --git a/src/Arborist/src/ExpressionOn_2.cs b/src/Arborist/src/ExpressionOn_2.cs index 5a037e4..f5ec929 100644 --- a/src/Arborist/src/ExpressionOn_2.cs +++ b/src/Arborist/src/ExpressionOn_2.cs @@ -18,4 +18,17 @@ public static Expression> Of(Expression> expressi /// public static Expression> Of(Expression> expression) => expression; + + /// + /// Grafts the provided expression onto the expression, + /// replacing references to its parameter with the body of the expression. + /// + public static Expression> Graft( + Expression> root, + Expression> branch + ) => + Expression.Lambda>( + body: ExpressionHelper.Replace(branch.Body, branch.Parameters[0], root.Body), + parameters: root.Parameters + ); } diff --git a/src/Arborist/src/ExpressionOn_3.cs b/src/Arborist/src/ExpressionOn_3.cs index 56ac195..309fc1f 100644 --- a/src/Arborist/src/ExpressionOn_3.cs +++ b/src/Arborist/src/ExpressionOn_3.cs @@ -18,4 +18,17 @@ public static Expression> Of(Expression> ex /// public static Expression> Of(Expression> expression) => expression; + + /// + /// Grafts the provided expression onto the expression, + /// replacing references to its parameter with the body of the expression. + /// + public static Expression> Graft( + Expression> root, + Expression> branch + ) => + Expression.Lambda>( + body: ExpressionHelper.Replace(branch.Body, branch.Parameters[0], root.Body), + parameters: root.Parameters + ); } diff --git a/src/Arborist/src/ExpressionOn_4.cs b/src/Arborist/src/ExpressionOn_4.cs index 3ae4f13..1d85538 100644 --- a/src/Arborist/src/ExpressionOn_4.cs +++ b/src/Arborist/src/ExpressionOn_4.cs @@ -18,4 +18,17 @@ public static Expression> Of(Expression public static Expression> Of(Expression> expression) => expression; + + /// + /// Grafts the provided expression onto the expression, + /// replacing references to its parameter with the body of the expression. + /// + public static Expression> Graft( + Expression> root, + Expression> branch + ) => + Expression.Lambda>( + body: ExpressionHelper.Replace(branch.Body, branch.Parameters[0], root.Body), + parameters: root.Parameters + ); } diff --git a/src/Arborist/test/GraftTests.cs b/src/Arborist/test/GraftTests.cs index a0195e4..df48a17 100644 --- a/src/Arborist/test/GraftTests.cs +++ b/src/Arborist/test/GraftTests.cs @@ -5,32 +5,40 @@ namespace Arborist; public class GraftTests { [Fact] public void Graft0_works_as_expected() { - var expected = Expression.Lambda>( - Expression.Property( - Expression.Constant("foo"), - typeof(string).GetProperty(nameof(string.Length))! - ) - ); - - var actual = ExpressionOnNone.Graft(() => "foo", str => str.Length); + var expected = ExpressionOnNone.Of(() => "foo".Length); + var actual = ExpressionOnNone.Graft(() => "foo", v => v.Length); Assert.Equivalent(expected, actual); } [Fact] public void Graft1_works_as_expected() { - var actual = ExpressionOn.Graft(c => c.Name, str => str.Length); - - var expected = Expression.Lambda>( - Expression.Property( - Expression.Property( - actual.Parameters[0], - typeof(Cat).GetProperty(nameof(Cat.Name))! - ), - typeof(string).GetProperty(nameof(string.Length))! - ), - actual.Parameters - ); + var expected = ExpressionOn.Of(a => a.Name.Length); + var actual = ExpressionOn.Graft(a => a.Name, v => v.Length); + + Assert.Equivalent(expected, actual); + } + + [Fact] + public void Graft2_works_as_expected() { + var expected = ExpressionOn.Of((a, b) => a.Name.Length); + var actual = ExpressionOn.Graft((a, b) => a.Name, v => v.Length); + + Assert.Equivalent(expected, actual); + } + + [Fact] + public void Graft3_works_as_expected() { + var expected = ExpressionOn.Of((a, b, c) => a.Name.Length); + var actual = ExpressionOn.Graft((a, b, c) => a.Name, v => v.Length); + + Assert.Equivalent(expected, actual); + } + + [Fact] + public void Graft4_works_as_expected() { + var expected = ExpressionOn.Of((a, b, c, d) => a.Name.Length); + var actual = ExpressionOn.Graft((a, b, c, d) => a.Name, v => v.Length); Assert.Equivalent(expected, actual); }