@@ -38,20 +38,22 @@ public sealed class BalancerAttributes : IDictionary<string, object?>, IReadOnly
3838 /// <summary>
3939 /// Gets a read-only collection of metadata attributes.
4040 /// </summary>
41- public static readonly BalancerAttributes Empty = new BalancerAttributes ( new ReadOnlyDictionary < string , object ? > ( new Dictionary < string , object ? > ( ) ) ) ;
41+ public static readonly BalancerAttributes Empty = new BalancerAttributes ( new Dictionary < string , object ? > ( ) , readOnly : true ) ;
4242
43- private readonly IDictionary < string , object ? > _attributes ;
43+ private readonly Dictionary < string , object ? > _attributes ;
44+ private readonly bool _readOnly ;
4445
4546 /// <summary>
4647 /// Initializes a new instance of the <see cref="BalancerAttributes"/> class.
4748 /// </summary>
48- public BalancerAttributes ( ) : this ( new Dictionary < string , object ? > ( ) )
49+ public BalancerAttributes ( ) : this ( new Dictionary < string , object ? > ( ) , readOnly : false )
4950 {
5051 }
5152
52- private BalancerAttributes ( IDictionary < string , object ? > attributes )
53+ private BalancerAttributes ( Dictionary < string , object ? > attributes , bool readOnly )
5354 {
5455 _attributes = attributes ;
56+ _readOnly = readOnly ;
5557 }
5658
5759 object ? IDictionary < string , object ? > . this [ string key ]
@@ -62,28 +64,49 @@ private BalancerAttributes(IDictionary<string, object?> attributes)
6264 }
6365 set
6466 {
67+ ValidateReadOnly ( ) ;
6568 _attributes [ key ] = value ;
6669 }
6770 }
6871
6972 ICollection < string > IDictionary < string , object ? > . Keys => _attributes . Keys ;
7073 ICollection < object ? > IDictionary < string , object ? > . Values => _attributes . Values ;
7174 int ICollection < KeyValuePair < string , object ? > > . Count => _attributes . Count ;
72- bool ICollection < KeyValuePair < string , object ? > > . IsReadOnly => _attributes . IsReadOnly ;
75+ bool ICollection < KeyValuePair < string , object ? > > . IsReadOnly => _readOnly || ( ( ICollection < KeyValuePair < string , object ? > > ) _attributes ) . IsReadOnly ;
7376 IEnumerable < string > IReadOnlyDictionary < string , object ? > . Keys => _attributes . Keys ;
7477 IEnumerable < object ? > IReadOnlyDictionary < string , object ? > . Values => _attributes . Values ;
7578 int IReadOnlyCollection < KeyValuePair < string , object ? > > . Count => _attributes . Count ;
7679 object ? IReadOnlyDictionary < string , object ? > . this [ string key ] => _attributes [ key ] ;
77- void IDictionary < string , object ? > . Add ( string key , object ? value ) => _attributes . Add ( key , value ) ;
78- void ICollection < KeyValuePair < string , object ? > > . Add ( KeyValuePair < string , object ? > item ) => _attributes . Add ( item ) ;
79- void ICollection < KeyValuePair < string , object ? > > . Clear ( ) => _attributes . Clear ( ) ;
80+ void IDictionary < string , object ? > . Add ( string key , object ? value )
81+ {
82+ ValidateReadOnly ( ) ;
83+ _attributes . Add ( key , value ) ;
84+ }
85+ void ICollection < KeyValuePair < string , object ? > > . Add ( KeyValuePair < string , object ? > item )
86+ {
87+ ValidateReadOnly ( ) ;
88+ ( ( ICollection < KeyValuePair < string , object ? > > ) _attributes ) . Add ( item ) ;
89+ }
90+ void ICollection < KeyValuePair < string , object ? > > . Clear ( )
91+ {
92+ ValidateReadOnly ( ) ;
93+ _attributes . Clear ( ) ;
94+ }
8095 bool ICollection < KeyValuePair < string , object ? > > . Contains ( KeyValuePair < string , object ? > item ) => _attributes . Contains ( item ) ;
8196 bool IDictionary < string , object ? > . ContainsKey ( string key ) => _attributes . ContainsKey ( key ) ;
82- void ICollection < KeyValuePair < string , object ? > > . CopyTo ( KeyValuePair < string , object ? > [ ] array , int arrayIndex ) => _attributes . CopyTo ( array , arrayIndex ) ;
97+ void ICollection < KeyValuePair < string , object ? > > . CopyTo ( KeyValuePair < string , object ? > [ ] array , int arrayIndex ) => ( ( ICollection < KeyValuePair < string , object ? > > ) _attributes ) . CopyTo ( array , arrayIndex ) ;
8398 IEnumerator < KeyValuePair < string , object ? > > IEnumerable < KeyValuePair < string , object ? > > . GetEnumerator ( ) => _attributes . GetEnumerator ( ) ;
8499 IEnumerator System . Collections . IEnumerable . GetEnumerator ( ) => ( ( System . Collections . IEnumerable ) _attributes ) . GetEnumerator ( ) ;
85- bool IDictionary < string , object ? > . Remove ( string key ) => _attributes . Remove ( key ) ;
86- bool ICollection < KeyValuePair < string , object ? > > . Remove ( KeyValuePair < string , object ? > item ) => _attributes . Remove ( item ) ;
100+ bool IDictionary < string , object ? > . Remove ( string key )
101+ {
102+ ValidateReadOnly ( ) ;
103+ return _attributes . Remove ( key ) ;
104+ }
105+ bool ICollection < KeyValuePair < string , object ? > > . Remove ( KeyValuePair < string , object ? > item )
106+ {
107+ ValidateReadOnly ( ) ;
108+ return ( ( ICollection < KeyValuePair < string , object ? > > ) _attributes ) . Remove ( item ) ;
109+ }
87110 bool IDictionary < string , object ? > . TryGetValue ( string key , out object ? value ) => _attributes . TryGetValue ( key , out value ) ;
88111 bool IReadOnlyDictionary < string , object ? > . ContainsKey ( string key ) => _attributes . ContainsKey ( key ) ;
89112 bool IReadOnlyDictionary < string , object ? > . TryGetValue ( string key , out object ? value ) => _attributes . TryGetValue ( key , out value ) ;
@@ -121,6 +144,7 @@ public bool TryGetValue<TValue>(BalancerAttributesKey<TValue> key, [MaybeNullWhe
121144 /// <param name="value">The value.</param>
122145 public void Set < TValue > ( BalancerAttributesKey < TValue > key , TValue value )
123146 {
147+ ValidateReadOnly ( ) ;
124148 _attributes [ key . Key ] = value ;
125149 }
126150
@@ -135,10 +159,55 @@ public void Set<TValue>(BalancerAttributesKey<TValue> key, TValue value)
135159 /// </returns>
136160 public bool Remove < TValue > ( BalancerAttributesKey < TValue > key )
137161 {
162+ ValidateReadOnly ( ) ;
138163 return _attributes . Remove ( key . Key ) ;
139164 }
140165
141- internal string DebuggerToString ( )
166+ private void ValidateReadOnly ( )
167+ {
168+ if ( _readOnly )
169+ {
170+ throw new NotSupportedException ( "Collection is read-only." ) ;
171+ }
172+ }
173+
174+ internal static bool DeepEquals ( BalancerAttributes ? x , BalancerAttributes ? y )
175+ {
176+ var xValues = x ? . _attributes ;
177+ var yValues = y ? . _attributes ;
178+
179+ if ( ReferenceEquals ( xValues , yValues ) )
180+ {
181+ return true ;
182+ }
183+
184+ if ( xValues == null || yValues == null )
185+ {
186+ return false ;
187+ }
188+
189+ if ( xValues . Count != yValues . Count )
190+ {
191+ return false ;
192+ }
193+
194+ foreach ( var kvp in xValues )
195+ {
196+ if ( ! yValues . TryGetValue ( kvp . Key , out var value ) )
197+ {
198+ return false ;
199+ }
200+
201+ if ( ! Equals ( kvp . Value , value ) )
202+ {
203+ return false ;
204+ }
205+ }
206+
207+ return true ;
208+ }
209+
210+ private string DebuggerToString ( )
142211 {
143212 return $ "Count = { _attributes . Count } ";
144213 }
0 commit comments