From b6de3a3b7296ffc88fb16fcf5d5ac3b0d8c46791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Standa=20Luke=C5=A1?= Date: Fri, 20 Dec 2024 21:22:39 +0100 Subject: [PATCH] v5 cleanup: Replace custom ReferenceEqualityComparer with the standard one --- .../Compilation/ErrorCheckingVisitor.cs | 2 +- src/Framework/Framework/Controls/Repeater.cs | 2 +- .../Utils/ReferenceEqualityComparer.cs | 66 +++++++++++++++---- 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/Framework/Framework/Compilation/ErrorCheckingVisitor.cs b/src/Framework/Framework/Compilation/ErrorCheckingVisitor.cs index 86413cde7..c7b7be47d 100644 --- a/src/Framework/Framework/Compilation/ErrorCheckingVisitor.cs +++ b/src/Framework/Framework/Compilation/ErrorCheckingVisitor.cs @@ -71,7 +71,7 @@ private void AddNodeErrors(DothtmlNode node, int priority) /// * the locations are processed using MapBindingLocation to make them useful in the context of a dothtml file Dictionary AnnotateBindingExceptionWithLocation(ResolvedBinding binding, DotvvmProperty? relatedProperty, IEnumerable errors) { - var result = new Dictionary(ReferenceEqualityComparer.Instance); + var result = new Dictionary(ReferenceEqualityComparer.Instance); void recurse(Exception exception, DotvvmCompilationSourceLocation? location) { if (result.ContainsKey(exception)) diff --git a/src/Framework/Framework/Controls/Repeater.cs b/src/Framework/Framework/Controls/Repeater.cs index 988f8bbf2..5d72e369d 100644 --- a/src/Framework/Framework/Controls/Repeater.cs +++ b/src/Framework/Framework/Controls/Repeater.cs @@ -250,7 +250,7 @@ private DotvvmControl CreateEmptyItem(IDotvvmRequestContext context) return emptyDataContainer; } - private readonly Dictionary childrenCache = new(ReferenceEqualityComparer.Instance); + private readonly Dictionary childrenCache = new(ReferenceEqualityComparer.Instance); private DotvvmControl AddItem(IList c, IDotvvmRequestContext context, object? item = null, int? index = null, bool allowMemoizationRetrieve = false, bool allowMemoizationStore = false) { if (allowMemoizationRetrieve && item != null && childrenCache.TryGetValue(item, out var container2) && container2.Parent == null) diff --git a/src/Framework/Framework/Utils/ReferenceEqualityComparer.cs b/src/Framework/Framework/Utils/ReferenceEqualityComparer.cs index 4c34d4126..630ae7188 100644 --- a/src/Framework/Framework/Utils/ReferenceEqualityComparer.cs +++ b/src/Framework/Framework/Utils/ReferenceEqualityComparer.cs @@ -1,16 +1,60 @@ -using System.Collections.Generic; -using System.Runtime.CompilerServices; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +#if !NET_5_0_OR_GREATER -namespace DotVVM.Framework.Utils +using System.Runtime.CompilerServices; + +namespace System.Collections.Generic { - // TODO next version: Replace with System.Collections.Generic.ReferenceEqualityComparer - internal class ReferenceEqualityComparer : IEqualityComparer - where T : class + /// + /// An that uses reference equality () + /// instead of value equality () when comparing two object instances. + /// + /// + /// The type cannot be instantiated. Instead, use the property + /// to access the singleton instance of this type. + /// + internal sealed class ReferenceEqualityComparer : IEqualityComparer, IEqualityComparer { - public static ReferenceEqualityComparer Instance { get; } = new ReferenceEqualityComparer(); - - - public bool Equals(T? x, T? y) => ReferenceEquals(x, y); - public int GetHashCode(T obj) => obj == null ? 0 : RuntimeHelpers.GetHashCode(obj); + private ReferenceEqualityComparer() { } + + /// + /// Gets the singleton instance. + /// + public static ReferenceEqualityComparer Instance { get; } = new ReferenceEqualityComparer(); + + /// + /// Determines whether two object references refer to the same object instance. + /// + /// The first object to compare. + /// The second object to compare. + /// + /// if both and refer to the same object instance + /// or if both are ; otherwise, . + /// + /// + /// This API is a wrapper around . + /// It is not necessarily equivalent to calling . + /// + public new bool Equals(object? x, object? y) => ReferenceEquals(x, y); + + /// + /// Returns a hash code for the specified object. The returned hash code is based on the object + /// identity, not on the contents of the object. + /// + /// The object for which to retrieve the hash code. + /// A hash code for the identity of . + /// + /// This API is a wrapper around . + /// It is not necessarily equivalent to calling . + /// + public int GetHashCode(object? obj) + { + // Depending on target framework, RuntimeHelpers.GetHashCode might not be annotated + // with the proper nullability attribute. We'll suppress any warning that might + // result. + return RuntimeHelpers.GetHashCode(obj!); + } } } +#endif