Leggere l' articolo sulle eccezioni di Eric Lippert è stato sicuramente un modo per aprire gli occhi su come dovrei affrontare le eccezioni, sia come produttore che come consumatore. Tuttavia, sto ancora lottando per definire una linea guida su come evitare di lanciare eccezioni fastidiose.
In particolare:
- Supponiamo di avere un metodo Save che può fallire perché a) Qualcun altro ha modificato il record prima di te oppure b) Il valore che stai tentando di creare esiste già . Queste condizioni sono prevedibili e non eccezionali, quindi invece di generare un'eccezione, decidi di creare una versione Try del tuo metodo, TrySave, che restituisce un valore booleano che indica se il salvataggio è riuscito. Ma se fallisce, come farà il consumatore a sapere qual è stato il problema? O sarebbe meglio restituire un enum che indica il risultato, tipo di Ok / RecordAlreadyModified / ValueAlreadyExists? Con integer. TryParse questo problema non esiste, poiché esiste solo una ragione per cui il metodo può fallire.
- L'esempio precedente è davvero una situazione fastidiosa? O lanciare un'eccezione in questo caso sarebbe il modo preferito? So che è così che viene fatto nella maggior parte delle librerie e dei framework, incluso il framework Entity.
- Come decidi quando creare una versione di prova del tuo metodo anziché fornire in anticipo un modo per testare se il metodo funzionerà o no? Attualmente sto seguendo queste linee guida:
- Se esiste la possibilità di una condizione di gara, crea una versione di prova. Ciò impedisce al consumatore di cogliere un'eccezione esogena. Ad esempio, nel metodo Salva descritto in precedenza.
- Se il metodo per testare la condizione praticamente farebbe tutto ciò che fa il metodo originale, quindi creare una versione di prova. Ad esempio, integer.TryParse ().
- In ogni altro caso, creare un metodo per testare la condizione.