La lettura di articolo sulle eccezioni di Eric Lippert è stata sicuramente una 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 irritanti.
In particolare:
- Supponiamo di avere un metodo di salvataggio che può fallire perché a) Qualcun altro ha modificato il record prima di , o b) il valore che stai tentando di creare esiste già . Queste condizioni sono da aspettarsi e non eccezionali, quindi, invece di lanciare 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 è il problema? O sarebbe meglio restituire un enum indicante il risultato, tipo Ok / RecordAlreadyModified / ValueAlreadyExists? Con integer.TryParse questo problema non esiste, poiché esiste un solo motivo per il quale il metodo può fallire.
- L'esempio precedente è davvero una situazione irritante? O fare un'eccezione in questo caso sarebbe il modo preferito? So che è come è fatto nella maggior parte delle librerie e dei framework, incluso il framework Entity.
- Come decidi quando creare una versione di prova del tuo metodo e fornire un modo per testare in anticipo se il metodo funzionerà o no? Attualmente sto seguendo queste linee guida:
- Se esiste la possibilità di una condizione di competizione, quindi crea una versione Prova. Ciò impedisce al consumatore di rilevare un'eccezione esogena. Ad esempio, nel metodo Save descritto in precedenza.
- Se il metodo per testare la condizione praticamente farebbe tutto ciò che fa il metodo originale, quindi creare una versione Try. Ad esempio, integer.TryParse ().
- In qualsiasi altro caso, crea un metodo per testare la condizione.