@@ -248,12 +248,12 @@ private class WritersForType
248
248
{
249
249
private const int MaxCachedWriterLookups = 100 ;
250
250
private readonly Dictionary < string , IPropertySetter > _underlyingWriters ;
251
- private readonly ConcurrentDictionary < StringObjectIdentityKey , IPropertySetter ? > _writerCache ;
251
+ private readonly ConcurrentDictionary < string , IPropertySetter ? > _referenceEqualityWritersCache ;
252
252
253
253
public WritersForType ( Type targetType )
254
254
{
255
255
_underlyingWriters = new Dictionary < string , IPropertySetter > ( StringComparer . OrdinalIgnoreCase ) ;
256
- _writerCache = new ConcurrentDictionary < StringObjectIdentityKey , IPropertySetter ? > ( ) ;
256
+ _referenceEqualityWritersCache = new ConcurrentDictionary < string , IPropertySetter ? > ( ReferenceEqualityComparer . Instance ) ;
257
257
258
258
foreach ( var propertyInfo in GetCandidateBindableProperties ( targetType ) )
259
259
{
@@ -318,9 +318,7 @@ public bool TryGetValue(string parameterName, [MaybeNullWhen(false)] out IProper
318
318
// having to hash the string. We only fall back on hashing the string if the cache gets full,
319
319
// which would only be in very unusual situations because components don't typically have many
320
320
// parameters, and the parameterName strings usually come from compile-time constants.
321
- var cacheKey = new StringObjectIdentityKey ( parameterName ) ;
322
-
323
- if ( ! _writerCache . TryGetValue ( cacheKey , out writer ) )
321
+ if ( ! _referenceEqualityWritersCache . TryGetValue ( parameterName , out writer ) )
324
322
{
325
323
_underlyingWriters . TryGetValue ( parameterName , out writer ) ;
326
324
@@ -331,36 +329,14 @@ public bool TryGetValue(string parameterName, [MaybeNullWhen(false)] out IProper
331
329
// lookup misses just as much as hits, since then we can more quickly identify
332
330
// incoming values that don't have a corresponding writer and thus will end up
333
331
// being passed as catch-all parameter values.
334
- if ( _writerCache . Count < MaxCachedWriterLookups )
332
+ if ( _referenceEqualityWritersCache . Count < MaxCachedWriterLookups )
335
333
{
336
- _writerCache . TryAdd ( cacheKey , writer ) ;
334
+ _referenceEqualityWritersCache . TryAdd ( parameterName , writer ) ;
337
335
}
338
336
}
339
337
340
338
return writer != null ;
341
339
}
342
-
343
- // Adapts a string dictionary to one which never uses string.GetHashCode.
344
- // Should only be used in the limited cases described above (i.e., when the
345
- // key values are nearly always interned, and the cache size is limited)
346
- private struct StringObjectIdentityKey : IEquatable < StringObjectIdentityKey >
347
- {
348
- private readonly string _value ;
349
-
350
- public StringObjectIdentityKey ( string value )
351
- {
352
- _value = value ;
353
- }
354
-
355
- public bool Equals ( [ AllowNull ] StringObjectIdentityKey other )
356
- => ReferenceEquals ( _value , other . _value ) ;
357
-
358
- public override bool Equals ( object ? obj )
359
- => obj is StringObjectIdentityKey other && ReferenceEquals ( _value , other . _value ) ;
360
-
361
- public override int GetHashCode ( )
362
- => RuntimeHelpers . GetHashCode ( _value ) ;
363
- }
364
340
}
365
341
}
366
342
}
0 commit comments