| Propriété | Valeur |
|---|---|
| Catégorie | Composition (JustDummies.Composition) |
| Sévérité | 🟡 Avertissement |
| Activée par défaut | Oui |
La distinction est déclarée sur un type d’élément dépourvu d’égalité de valeur. Le comparateur par défaut retombe sur l’égalité de référence, et chaque élément que le générateur construit est une nouvelle instance — l’exigence est donc satisfaite par construction et ne contraint rien.
La collection peut contenir plusieurs fois la même valeur, ce que la déclaration lui demande précisément de ne pas faire.
Non conforme
public sealed class Box { // ni Equals ni IEquatable
public Box(int value) { Value = value; }
public int Value { get; }
}
Any.ListOf(Any.Int32().Between(1, 2).As(v => new Box(v))).Distinct().WithCount(6) // JD028
Mesuré sur la bibliothèque, cette déclaration rend six boîtes « distinctes » portant [1, 1, 1, 2, 1, 2] — au vert, à chaque fois.
Conforme
Donner une égalité de valeur au type d’élément :
public sealed record Box(int Value);
Any.ListOf(Any.Int32().Between(1, 2).As(v => new Box(v))).Distinct().WithCount(6)
// AnyGenerationException : the element generator produced only 2 distinct value(s)
La déclaration signifie maintenant quelque chose, et la demande impossible est signalée.
Ou répondre explicitement à la question de l’égalité :
Any.ListOf(generator).Distinct(new BoxByValue())
Any.SetOf(generator, new BoxByValue())
Pourquoi la bibliothèque ne peut pas le signaler
De son côté, l’exigence est tenue : les tirages sont réellement deux à deux différents sous le comparateur qu’on lui a donné, et il n’y a rien à redire. Seule l’égalité du type d’élément distingue le cas inerte du cas réel, et elle est visible sur le site d’appel.
Ce qui n’est pas signalé
- Un générateur qui restitue des instances existantes.
Any.SetOf(Any.OneOf(first, second))rend les références mêmes qu’on lui a confiées : tirer deux fois le même membre donne la même référence, et la distinction s’applique exactement comme demandé. - Un type d’élément qui est un type valeur, un record, une implémentation d’
IEquatable<T>, ou qui redéfinitEquals— n’importe où dans sa chaîne de bases. - Un type d’élément non scellé. Une instance dérivée est libre d’ajouter l’égalité qui manque à la base, et la règle ne prétend que ce qu’elle peut prouver.
- Une projection susceptible de rendre une instance partagée (
As(v => Lookup(v))) ; seule une chaîne qui construit prouvablement une valeur neuve ici est concernée. - Toute collection à laquelle un comparateur explicite est fourni.