Je développe une bibliothèque destinée à être publiée. Il contient diverses méthodes permettant de manipuler des ensembles d'objets: générer, inspecter, partitionner et projeter les ensembles dans de nouveaux formulaires. Le cas échéant, il s'agit d'une bibliothèque de classe C # contenant des extensions de style LINQ IEnumerable
, à publier sous forme de package NuGet.
Certaines méthodes de cette bibliothèque peuvent recevoir des paramètres d'entrée non satisfaisants. Par exemple, dans les méthodes combinatoires, il existe une méthode pour générer tous les ensembles de n éléments pouvant être construits à partir d’un ensemble source de m éléments. Par exemple, étant donné l'ensemble:
1, 2, 3, 4, 5
et demander des combinaisons de 2 produirait:
1, 2
1, 3
1, 4
etc ...
5, 3
5, 4
Maintenant, il est évidemment possible de demander quelque chose qui ne peut pas être fait, comme donner un ensemble de 3 éléments, puis demander des combinaisons de 4 éléments tout en définissant l'option qui dit qu'il ne peut utiliser chaque élément qu'une seule fois.
Dans ce scénario, chaque paramètre est individuellement valide:
- La collection source n'est pas null et contient des éléments
- La taille des combinaisons demandée est un entier positif différent de zéro
- Le mode demandé (utiliser chaque élément une seule fois) est un choix valide
Cependant, l'état des paramètres, pris ensemble, pose des problèmes.
Dans ce scénario, vous attendriez-vous que la méthode lève une exception (par exemple InvalidOperationException
) ou renvoie une collection vide? Cela me semble valable:
- Vous ne pouvez pas produire de combinaisons de n éléments à partir d'un ensemble de m éléments où n> m si vous ne pouvez utiliser chaque élément qu'une seule fois. Cette opération peut donc être considérée comme impossible
InvalidOperationException
. - L'ensemble des combinaisons de taille n pouvant être produites à partir de m éléments lorsque n> m est un ensemble vide; aucune combinaison ne peut être produite.
L'argument pour un ensemble vide
Ma première préoccupation est qu’une exception empêche l’enchaînement idiomatique de méthodes de type LINQ lorsque vous traitez avec des jeux de données dont la taille peut être inconnue. En d'autres termes, vous voudrez peut-être faire quelque chose comme ceci:
var result = someInputSet
.CombinationsOf(4, CombinationsGenerationMode.Distinct)
.Select(combo => /* do some operation to a combination */)
.ToList();
Si votre jeu d'entrées est de taille variable, le comportement de ce code est imprévisible. Si .CombinationsOf()
une exception someInputSet
contient moins de 4 éléments, ce code échouera parfois au moment de l'exécution sans vérification préalable. Dans l'exemple ci-dessus, cette vérification est triviale, mais si vous l'appelez à mi-chemin d'une chaîne plus longue de LINQ, cela peut devenir fastidieux. S'il retourne un ensemble vide, il result
sera vide, ce qui peut vous satisfaire parfaitement.
L'argument pour une exception
Ma deuxième préoccupation est que renvoyer un ensemble vide peut masquer des problèmes - si vous appelez cette méthode à mi-chemin d’une chaîne de LINQ et qu’elle renvoie silencieusement un ensemble vide, vous risquez de rencontrer des problèmes quelques étapes plus tard ou de vous retrouver avec un objet vide. résultat, et il n’est peut-être pas évident de savoir comment cela s’est passé puisque vous aviez certainement quelque chose dans le jeu d’entrée.
À quoi vous attendez-vous et quel est votre argument?