JustDummies

Juste des dummies, mais redoutablement efficaces.

Sections de la documentation

JD028 : InertDistinctness

PropriétéValeur
CatégorieComposition (JustDummies.Composition)
Sévérité🟡 Avertissement
Activée par défautOui

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éfinit Equals — 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.

Lire la source, ou la corriger là-bas ouvre un nouvel onglet· Repris depuis lib-v1.0.0-preview.6