Ho usato per creare interfacce con IEnumerable<T>
come tipo di ritorno, ogni volta che voglio specificare che un particolare output è di sola lettura. Mi piace perché è minimalista, nasconde i dettagli di implementazione e disaccoppia un callee da un chiamante.Un problema con la gestione delle eccezioni per IEnumerable <T>, è pigro-dipendente
Ma di recente un mio collega ha sostenuto che IEnumerable<T>
dovrebbero essere tenuti per gli scenari che coinvolgono valutazione pigra solo, altrimenti non è chiaro per un metodo chiamante, in cui la gestione delle eccezioni dovrebbe prendere il suo posto - intorno a una chiamata di metodo o intorno ad un iterazione. Quindi per i casi di valutazione desiderosi con un'uscita di sola lettura, dovrei usare uno ReadOnlyCollection
.
Suoni abbastanza ragionevoli per me, ma cosa consiglieresti? Sei d'accordo con quella convenzione per IEnumerable? O ci sono metodi migliori per la gestione delle eccezioni attorno a IEnumerable?
Nel caso in cui la mia domanda non sia chiara, ho creato una classe di esempio che illustra il problema. Due metodi in qui hanno esattamente la stessa firma, ma richiedono diversa gestione delle eccezioni:
public class EvilEnumerable
{
IEnumerable<int> Throw()
{
throw new ArgumentException();
}
IEnumerable<int> LazyThrow()
{
foreach (var item in Throw())
{
yield return item;
}
}
public void Run()
{
try
{
Throw();
}
catch (ArgumentException)
{
Console.WriteLine("immediate throw");
}
try
{
LazyThrow();
}
catch (ArgumentException)
{
Console.WriteLine("No exception is thrown.");
}
try
{
foreach (var item in LazyThrow())
{
//do smth
}
}
catch (ArgumentException)
{
Console.WriteLine("lazy throw");
}
}
}
Update 1. La questione non si limita alla sola ArgumentException. Si tratta delle migliori pratiche per creare interfacce di classe intuitive, che ti diano una risposta se restituiscono risultati di valutazione pigri o meno, perché questo influenza l'approccio di gestione delle eccezioni.
È assurdo supporre che IEnumerable debba essere tenuto a una valutazione lenta, in quanto non è mai stato collegato alla valutazione pigra in primo luogo. IEnumerable esisteva prima che la valutazione lazy fosse un paradigma comune in C#. – Joren