99namespace FastCloner . Tests ;
1010public class FailureHypothesisTests
1111{
12- /// <summary>
13- /// Demonstrates a weakness: <see cref="FastClonerSafeTypes"/> assumes any class that overrides
14- /// <c>GetHashCode</c> has value-based hashing (<c>HasStableHashSemantics == true</c>). This drives
15- /// hash-based collections through a memberwise (raw field) clone path that copies the internal
16- /// <c>_slots</c>/<c>_buckets</c> arrays verbatim. When the override actually returns an identity-based
17- /// hash (e.g. <c>RuntimeHelpers.GetHashCode(this)</c>), the cloned bucket entries store the *original*
18- /// object's identity hash, but the elements inside are themselves deep-cloned and therefore have a
19- /// brand-new identity hash. The cloned set/dictionary is structurally corrupt: lookups by the
20- /// cloned key miss, even though the key is the very element stored in the clone.
21- /// </summary>
2212 private sealed class IdentityHashedKey
2313 {
2414 public string Tag { get ; set ; } = "" ;
@@ -66,13 +56,7 @@ await Assert.That(clone.TryGetValue(cloneKey, out int value)).IsTrue()
6656 "FastCloner stores stale identity hashes from the original key in the cloned bucket." ) ;
6757 await Assert . That ( value ) . IsEqualTo ( 42 ) ;
6858 }
69-
70- /// <summary>
71- /// Type whose override would normally throw on a default-state probe instance (Tag is null, ToUpper NREs).
72- /// Without an opt-in, the probe catches the throw and conservatively rebuilds the collection. With
73- /// <see cref="FastClonerStableHashAttribute"/> the type author asserts the override is value-based, so
74- /// FastCloner skips the probe and uses the fast memberwise path. Lookups in the cloned set must still work.
75- /// </summary>
59+
7660 [ FastClonerStableHash ]
7761 private sealed class ProbeUnfriendlyButStableKey
7862 {
@@ -82,11 +66,7 @@ public override bool Equals(object? obj)
8266 => obj is ProbeUnfriendlyButStableKey other
8367 && string . Equals ( Tag , other . Tag , StringComparison . OrdinalIgnoreCase ) ;
8468 }
85-
86- /// <summary>
87- /// Same hash semantics as <see cref="ProbeUnfriendlyButStableKey"/> but without the attribute. Used to
88- /// assert that the attribute really is what changes the verdict (not some unrelated probe success).
89- /// </summary>
69+
9070 private sealed class ProbeUnfriendlyKeyNoAttribute
9171 {
9272 public string Tag { get ; set ; } = "" ;
0 commit comments