1+ using NUnit . Framework ;
2+ using System ;
3+ using System . Linq . Expressions ;
4+ #if LIGHT_EXPRESSION
5+ using System . Text ;
6+ using static FastExpressionCompiler . LightExpression . Expression ;
7+ namespace FastExpressionCompiler . LightExpression . IssueTests
8+ #else
9+ using static System . Linq . Expressions . Expression ;
10+ namespace FastExpressionCompiler . IssueTests
11+ #endif
12+ {
13+ [ TestFixture ]
14+ public class Issue293_Recursive_Methods : ITest
15+ {
16+ public int Run ( )
17+ {
18+ Test_Recursive_Expression ( ) ;
19+ return 1 ;
20+ }
21+
22+ [ Test ]
23+ public void Test_Recursive_Expression ( )
24+ {
25+ var expr = MakeFactorialExpression < int > ( ) ;
26+
27+ expr . PrintCSharp ( ) ;
28+ var fs = expr . CompileSys ( ) ;
29+ fs . PrintIL ( ) ;
30+ var res = fs ( 4 ) ;
31+
32+ var f = expr . CompileFast ( true ) ;
33+ f . PrintIL ( ) ;
34+ var res2 = f ( 4 ) ;
35+
36+ Assert . AreEqual ( res , res2 ) ;
37+ }
38+
39+ //from https://chriscavanagh.wordpress.com/2012/06/18/recursive-methods-in-expression-trees/
40+ public Expression < Func < T , T > > MakeFactorialExpression < T > ( )
41+ {
42+ var nParam = Expression . Parameter ( typeof ( T ) , "n" ) ;
43+ var methodVar = Expression . Variable ( typeof ( Func < T , T > ) , "factorial" ) ;
44+ var one = Expression . Convert ( Expression . Constant ( 1 ) , typeof ( T ) ) ;
45+
46+ return Expression . Lambda < Func < T , T > > (
47+ Expression . Block (
48+ // Func<uint, uint> method;
49+ new [ ] { methodVar } ,
50+ // method = n => ( n <= 1 ) ? 1 : n * method( n - 1 );
51+ Expression . Assign (
52+ methodVar ,
53+ Expression . Lambda < Func < T , T > > (
54+ Expression . Condition (
55+ // ( n <= 1 )
56+ Expression . LessThanOrEqual ( nParam , one ) ,
57+ // 1
58+ one ,
59+ // n * method( n - 1 )
60+ Expression . Multiply (
61+ // n
62+ nParam ,
63+ // method( n - 1 )
64+ Expression . Invoke (
65+ methodVar ,
66+ Expression . Subtract ( nParam , one ) ) ) ) ,
67+ nParam ) ) ,
68+ // return method( n );
69+ Expression . Invoke ( methodVar , nParam ) ) ,
70+ nParam ) ;
71+ }
72+ }
73+ }
0 commit comments