Tôi đã có một loạt các lớp học có thể Process()
đối tượng, và trở về đối tượng của mình:Quấn một IEnumerable và bắt ngoại lệ
public override IEnumerable<T> Process(IEnumerable<T> incoming) { ... }
Tôi muốn viết một lớp xử lý có thể quấn một trong những nhà chế biến, và đăng nhập bất kỳ ngoại lệ không thể bắt buộc nào mà phương thức được bọc Process()
có thể bị ném. Ý tưởng đầu tiên của tôi là một cái gì đó như thế này:
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;
}
}
nhưng điều này không hoạt động, do CS1626: Cannot yield a value in the body of a try block with a catch clause.
Vì vậy, tôi muốn viết một cái gì đó tương đương về khái niệm nhưng biên dịch. :-) Tôi đã có điều này:
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;
}
}
nhưng điều đó phức tạp hơn tôi mong đợi và tôi không hoàn toàn chắc chắn về tính chính xác của nó hoặc không có cách nào đơn giản hơn nhiều.
Tôi có đi đúng hướng ở đây không? Có cách nào dễ hơn không?
Điều gì về việc triển khai IEnumerable trực tiếp và bắt ngoại lệ bên trong MoveNext và Hiện tại của bạn? –
@Matt, tôi nghĩ đó là câu trả lời đúng. Bạn nên làm như vậy. Không có gì sai với ngắn và ngọt ngào. :) –
Tại sao không chỉ loại bỏ vòng lặp foreach và sản lượng? –