ho un mucchio di classi che possono Process()
oggetti, e ritornano i propri oggetti:Wrap un IEnumerable e cattura eccezioni
public override IEnumerable<T> Process(IEnumerable<T> incoming) { ... }
Voglio scrivere una classe processore in grado di avvolgere uno di questi processori, e registra eventuali eccezioni non rilevate che il metodo spostato Process()
potrebbe generare. La mia prima idea era qualcosa di simile:
public override IEnumerable<T> Process(IEnumerable<T> incoming) {
try {
foreach (var x in this.processor.Process(incoming)) {
yield return x;
}
} catch (Exception e) {
WriteToLog(e);
throw;
}
}
ma questo non funziona, a causa di CS1626: Cannot yield a value in the body of a try block with a catch clause.
Quindi voglio scrivere qualcosa che sia concettualmente equivalente ma compilato. :-) Ho questo:
public override IEnumerable<T> Process(IEnumerable<T> incoming) {
IEnumerator<T> walker;
try {
walker = this.processor.Process(incoming).GetEnumerator();
} catch (Exception e) {
WriteToLog(e);
throw;
}
while (true) {
T value;
try {
if (!walker.MoveNext()) {
break;
}
value = walker.Current;
} catch (Exception e) {
WriteToLog(e);
throw;
}
yield return value;
}
}
ma questo è più complessa di quanto avevo sperato, e io non sono del tutto certo di una sua correttezza o che non c'è un modo molto più semplice.
Sono sulla pista giusta qui? C'è un modo più semplice?
Cosa ne pensi dell'implementazione di IEnumerable e delle eccezioni all'interno di MoveNext e Current? –
@ Matt, penso che sia la risposta corretta. Avresti dovuto renderlo tale. Niente di male con breve e dolce. :) –
Perché non basta rimuovere il ciclo foreach e cedere? –