@@ -19,8 +19,64 @@ public static Expression Assign(Expression left, Expression right)
19
19
20
20
public static Expression PropertyOrFieldPath ( Expression expr , string path )
21
21
{
22
- var props = path . Split ( '.' ) ;
23
- return props . Aggregate ( expr , PropertyOrField ) ;
22
+ Expression current = expr ;
23
+ string [ ] props = path . Split ( '.' ) ;
24
+
25
+ for ( int i = 0 ; i < props . Length ; i ++ )
26
+ {
27
+ Exception initialException ;
28
+
29
+ try
30
+ {
31
+ string prop = props [ i ] ;
32
+ current = PropertyOrField ( current , prop ) ;
33
+ continue ;
34
+ }
35
+ catch ( Exception ex ) when ( props . Length - i > 1 ) // Only catch when parts remain
36
+ {
37
+ // Store the exception to rethrow in the end if the alternative approach fails
38
+ initialException = ex ;
39
+ }
40
+
41
+ // For dynamically built types, it is possible to have periods in the property name.
42
+ // Rejoin an incrementing number of parts with periods to try and find a property match.
43
+ try
44
+ {
45
+ ( current , int combinationLength ) = PropertyOrFieldPathWithPeriods ( current , props [ i ..] ) ;
46
+ i += combinationLength - 1 ;
47
+ }
48
+ catch
49
+ {
50
+ // Rethrow the original exception for the first part
51
+ ExceptionDispatchInfo . Capture ( initialException ) . Throw ( ) ;
52
+ }
53
+ }
54
+
55
+ return current ;
56
+ }
57
+
58
+ private static ( Expression Expression , int CombinationLength ) PropertyOrFieldPathWithPeriods ( Expression expr , string [ ] path )
59
+ {
60
+ if ( path . Length < 2 )
61
+ {
62
+ throw new ArgumentException ( $ "Value should contain at least 2 elements, got { path . Length } .", nameof ( path ) ) ;
63
+ }
64
+
65
+ for ( int count = 2 ; count <= path . Length ; count ++ )
66
+ {
67
+ try
68
+ {
69
+ string prop = string . Join ( '.' , path [ ..count ] ) ;
70
+ return ( PropertyOrField ( expr , prop ) , count ) ;
71
+ }
72
+ catch when ( count < path . Length )
73
+ {
74
+ // Only throw for the last element, no property or field was found
75
+ }
76
+ }
77
+
78
+ // This is not reachable, right?
79
+ throw new NotSupportedException ( "This should not be reachable." ) ;
24
80
}
25
81
26
82
private static Expression PropertyOrField ( Expression expr , string prop )
0 commit comments