Sto sviluppando una libreria destinata alla pubblicazione pubblica. Contiene vari metodi per operare su insiemi di oggetti - generare, ispezionare, partizionare e proiettare gli insiemi in nuove forme. Nel caso sia rilevante, è una libreria di classi C # contenente estensioni stile LINQ su IEnumerable
, da rilasciare come pacchetto NuGet.
Alcuni dei metodi in questa libreria possono ricevere parametri di input insoddisfacenti. Ad esempio, nei metodi combinatori, esiste un metodo per generare tutti gli insiemi di elementi n che possono essere costruiti da un set sorgente di elementi m . Ad esempio, dato il set:
1, 2, 3, 4, 5
e chiedere combinazioni di 2 produrrebbe:
1, 2
1, 3
1, 4
etc...
5, 3
5, 4
Ora, è ovviamente possibile chiedere qualcosa che non può essere fatto, come dargli un set di 3 elementi e poi chiedere combinazioni di 4 elementi mentre si imposta l'opzione che dice che può usare ogni oggetto una sola volta.
In questo scenario, ogni parametro è individualmente valido:
- La raccolta di origine non è nullo e contiene elementi
- La dimensione richiesta di combinazioni è un intero diverso da zero positivo
- La modalità richiesta (usa ogni oggetto una sola volta) è una scelta valida
Tuttavia, lo stato dei parametri quando presi insieme causa problemi.
In questo scenario, ti aspetteresti che il metodo generi un'eccezione (ad esempio InvalidOperationException
) o restituisca una raccolta vuota? O sembra valido per me:
- Non puoi produrre combinazioni di elementi n da un insieme di elementi m dove n > m se ti è consentito utilizzare ogni oggetto solo una volta, quindi questa operazione può essere ritenuta impossibile, quindi
InvalidOperationException
. - L'insieme di combinazioni di dimensioni n che possono essere prodotte da elementi m quando n > m è un set vuoto; nessuna combinazione può essere prodotta.
L'argomento per un set vuoto
La mia prima preoccupazione è che un'eccezione impedisce il concatenamento di metodi in stile LINQ idiomatico quando si ha a che fare con set di dati che possono avere dimensioni sconosciute. In altre parole, potresti voler fare qualcosa di simile:
var result = someInputSet
.CombinationsOf(4, CombinationsGenerationMode.Distinct)
.Select(combo => /* do some operation to a combination */)
.ToList();
Se il tuo set di input è di dimensioni variabili, il comportamento di questo codice è imprevedibile. Se .CombinationsOf()
genera un'eccezione quando someInputSet
ha meno di 4 elementi, allora questo codice a volte fallirà in fase di esecuzione senza alcuni controlli preliminari. Nell'esempio precedente questo controllo è banale, ma se lo chiami a metà di una catena più lunga di LINQ, questo potrebbe diventare noioso. Se restituisce un set vuoto, result
sarà vuoto, il che potresti essere perfettamente soddisfatto.
L'argomento per un'eccezione
La mia seconda preoccupazione è che la restituzione di un set vuoto potrebbe nascondere problemi: se si chiama questo metodo a metà di una catena di LINQ e viene restituito un set vuoto in modo silenzioso, è possibile che si verifichino problemi qualche passo dopo o si trovi con un set di risultati vuoto, e potrebbe non essere ovvio come ciò è accaduto dato che hai sicuramente qualcosa nel set di input.
Che cosa ti aspetti e qual è il tuo argomento?