@@ -5,9 +5,11 @@ namespace Fluid
55{
66 public class DefaultMemberAccessStrategy : MemberAccessStrategy
77 {
8- private readonly object _synLock = new ( ) ;
8+ private readonly Lock _synLock = new ( ) ;
99
10- private Dictionary < Type , Dictionary < string , IMemberAccessor > > _map = new Dictionary < Type , Dictionary < string , IMemberAccessor > > ( ) ;
10+ private readonly record struct Key ( Type Type , string Name ) ;
11+
12+ private Dictionary < Key , IMemberAccessor > _map = new ( ) ;
1113
1214 public override IMemberAccessor GetAccessor ( Type type , string name )
1315 {
@@ -51,16 +53,7 @@ private IMemberAccessor GetAccessorUnlikely(Type type, string name)
5153 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
5254 private bool TryGetAccessor ( Type type , string name , out IMemberAccessor accessor )
5355 {
54- if ( _map . TryGetValue ( type , out var typeMap ) )
55- {
56- if ( typeMap . TryGetValue ( name , out accessor ) || typeMap . TryGetValue ( "*" , out accessor ) )
57- {
58- return true ;
59- }
60- }
61-
62- accessor = null ;
63- return false ;
56+ return _map . TryGetValue ( new Key ( type , name ) , out accessor ) || _map . TryGetValue ( new Key ( type , "*" ) , out accessor ) ;
6457 }
6558
6659 public override void Register ( Type type , IEnumerable < KeyValuePair < string , IMemberAccessor > > accessors )
@@ -75,29 +68,39 @@ public override void Register(Type type, IEnumerable<KeyValuePair<string, IMembe
7568 lock ( _synLock )
7669 {
7770 // Clone current dictionary
78- var temp = new Dictionary < Type , Dictionary < string , IMemberAccessor > > ( _map ) ;
71+ var temp = IgnoreCasing
72+ ? new Dictionary < Key , IMemberAccessor > ( _map , KeyIgnoreCaseComparer . Instance )
73+ : new Dictionary < Key , IMemberAccessor > ( _map ) ;
7974
80- // Clone inner dictionaries
81- foreach ( var typeEntry in temp )
75+ foreach ( var accessor in accessors )
8276 {
83- var entry = new Dictionary < string , IMemberAccessor > ( typeEntry . Value ) ;
77+ temp [ new Key ( type , accessor . Key ) ] = accessor . Value ;
8478 }
8579
86- if ( ! temp . TryGetValue ( type , out var typeMap ) )
87- {
88- typeMap = new Dictionary < string , IMemberAccessor > ( IgnoreCasing
89- ? StringComparer . OrdinalIgnoreCase
90- : StringComparer . Ordinal ) ;
80+ _map = temp ;
81+ }
82+ }
9183
92- temp [ type ] = typeMap ;
93- }
84+ private sealed class KeyIgnoreCaseComparer : IEqualityComparer < Key >
85+ {
86+ public static readonly KeyIgnoreCaseComparer Instance = new ( ) ;
9487
95- foreach ( var accessor in accessors )
96- {
97- typeMap [ accessor . Key ] = accessor . Value ;
98- }
88+ private KeyIgnoreCaseComparer ( )
89+ {
90+ }
9991
100- _map = temp ;
92+ public bool Equals ( Key x , Key y )
93+ {
94+ return x . Type == y . Type && string . Equals ( x . Name , y . Name , StringComparison . OrdinalIgnoreCase ) ;
95+ }
96+
97+ public int GetHashCode ( Key obj )
98+ {
99+ #if NET6_0_OR_GREATER
100+ return HashCode . Combine ( obj . Type , obj . Name . GetHashCode ( StringComparison . OrdinalIgnoreCase ) ) ;
101+ #else
102+ return obj . Type . GetHashCode ( ) ^ obj . Name . ToUpperInvariant ( ) . GetHashCode ( ) ;
103+ #endif
101104 }
102105 }
103106 }
0 commit comments