Max*_*kin 7 c# ienumerable exception-handling
IEnumerable<T>每当我想指定特定输出是只读时,我曾经用返回类型创建接口.我喜欢它,因为它是简约的,隐藏实现细节并将被调用者与调用者分离.
但是最近我的一位同事认为IEnumerable<T>应该保留仅涉及延迟评估的场景,否则它不清楚调用方法,异常处理应该采取它的位置 - 围绕方法调用或围绕迭代.那么对于具有只读输出的急切评估案例,我应该使用a ReadOnlyCollection.
对我来说听起来很合理,但你会推荐什么?你同意IEnumerable的约定吗?或者IEnumerable有更好的异常处理方法吗?
如果我的问题不清楚,我做了一个样本课来说明问题.这里的两个方法具有完全相同的签名,但它们需要不同的异常处理:
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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新1.问题不仅限于ArgumentException.它是关于创建友好类接口的最佳实践,它告诉您它们是否返回惰性求值结果,因为这会影响异常处理方法.
Mar*_*ell 10
这里真正的问题是延迟执行.在参数检查的情况下,您可以通过添加第二个方法来完成此操作:
IEnumerable<int> LazyThrow() {
// TODO: check args, throwing exception
return LazyThrowImpl();
}
IEnumerable<int> LazyThrowImpl() {
// TODO: lazy code using yield
}
Run Code Online (Sandbox Code Playgroud)
例外发生; 即使对于非延迟结果(List<T>例如),您也可能会遇到错误(可能是在迭代时另一个线程调整列表).上述方法允许您提前尽可能地减少意外的副作用yield和延迟执行.
| 归档时间: |
|
| 查看次数: |
1935 次 |
| 最近记录: |