55// Created: 2009.05.06
66
77using System . Linq . Expressions ;
8- using Xtensive . Core ;
8+ using System . Collections . ObjectModel ;
99
1010namespace Xtensive . Linq
1111{
@@ -103,14 +103,38 @@ private bool Visit(Expression x, Expression y)
103103 }
104104 }
105105
106- private bool VisitListInit ( ListInitExpression x , ListInitExpression y )
106+ private bool ElementInitsAreEqual ( ReadOnlyCollection < ElementInit > x , ReadOnlyCollection < ElementInit > y )
107107 {
108- var self = this ; // To allow struct's methods inside closures
109- return VisitNew ( x . NewExpression , y . NewExpression )
110- && x . Initializers . Count == y . Initializers . Count
111- && x . Initializers
112- . Zip ( y . Initializers )
113- . All ( p => self . VisitElementInit ( p . First , p . Second ) ) ;
108+ var count = x . Count ;
109+ if ( count != y . Count ) {
110+ return false ;
111+ }
112+
113+ for ( int i = 0 ; i < count ; ++ i ) {
114+ if ( ! VisitElementInit ( x [ i ] , y [ i ] ) ) {
115+ return false ;
116+ }
117+ }
118+ return true ;
119+ }
120+
121+ private bool VisitListInit ( ListInitExpression x , ListInitExpression y ) =>
122+ VisitNew ( x . NewExpression , y . NewExpression ) && ElementInitsAreEqual ( x . Initializers , y . Initializers ) ;
123+
124+ private bool MemberBindingsAreEqual ( ReadOnlyCollection < MemberBinding > xBindings , ReadOnlyCollection < MemberBinding > yBindings )
125+ {
126+ var count = xBindings . Count ;
127+ if ( count != yBindings . Count ) {
128+ return false ;
129+ }
130+
131+ for ( int i = 0 ; i < count ; ++ i ) {
132+ if ( ! VisitMemberBinding ( xBindings [ i ] , yBindings [ i ] ) ) {
133+ return false ;
134+ }
135+ }
136+
137+ return true ;
114138 }
115139
116140 /// <summary>
@@ -119,45 +143,19 @@ private bool VisitListInit(ListInitExpression x, ListInitExpression y)
119143 /// <param name="x">The x.</param>
120144 /// <param name="y">The y.</param>
121145 /// <returns></returns>
122- private bool VisitMemberInit ( MemberInitExpression x , MemberInitExpression y )
123- {
124- var self = this ; // To allow struct's methods inside closures
125- return VisitNew ( x . NewExpression , y . NewExpression )
126- && x . Bindings . Count == y . Bindings . Count
127- && x . Bindings
128- . Zip ( y . Bindings )
129- . All ( p => self . VisitMemberBinding ( p . First , p . Second ) ) ;
130- }
146+ private bool VisitMemberInit ( MemberInitExpression x , MemberInitExpression y ) =>
147+ VisitNew ( x . NewExpression , y . NewExpression ) && MemberBindingsAreEqual ( x . Bindings , y . Bindings ) ;
131148
132- private bool VisitMemberBinding ( MemberBinding x , MemberBinding y )
133- {
134- var bindingType = x . BindingType ;
135- if ( bindingType != y . BindingType || x . Member != y . Member )
136- return false ;
137- var self = this ; // To allow struct's methods inside closures
138- switch ( bindingType ) {
139- case MemberBindingType . Assignment :
140- var ax = ( MemberAssignment ) x ;
141- var ay = ( MemberAssignment ) y ;
142- return Visit ( ax . Expression , ay . Expression ) ;
143- case MemberBindingType . MemberBinding :
144- var mbx = ( MemberMemberBinding ) x ;
145- var mby = ( MemberMemberBinding ) y ;
146- return mbx . Bindings . Count == mby . Bindings . Count
147- && mbx . Bindings
148- . Zip ( mby . Bindings )
149- . All ( p => self . VisitMemberBinding ( p . First , p . Second ) ) ;
150- case MemberBindingType . ListBinding :
151- var mlx = ( MemberListBinding ) x ;
152- var mly = ( MemberListBinding ) y ;
153- return mlx . Initializers . Count == mly . Initializers . Count
154- && mlx . Initializers
155- . Zip ( mly . Initializers )
156- . All ( p => self . VisitElementInit ( p . First , p . Second ) ) ;
157- default :
158- throw new ArgumentOutOfRangeException ( ) ;
159- }
160- }
149+ private bool VisitMemberBinding ( MemberBinding x , MemberBinding y ) =>
150+ x . BindingType is var bindingType
151+ && bindingType == y . BindingType
152+ && x . Member == y . Member
153+ && bindingType switch {
154+ MemberBindingType . Assignment => Visit ( ( ( MemberAssignment ) x ) . Expression , ( ( MemberAssignment ) y ) . Expression ) ,
155+ MemberBindingType . MemberBinding => MemberBindingsAreEqual ( ( ( MemberMemberBinding ) x ) . Bindings , ( ( MemberMemberBinding ) y ) . Bindings ) ,
156+ MemberBindingType . ListBinding => ElementInitsAreEqual ( ( ( MemberListBinding ) x ) . Initializers , ( ( MemberListBinding ) y ) . Initializers ) ,
157+ _ => throw new ArgumentOutOfRangeException ( )
158+ } ;
161159
162160 private bool VisitElementInit ( ElementInit x , ElementInit y )
163161 {
0 commit comments