如果我有以下工作代码:
List<MyClass> results = new List<MyClass>();
for(int i = 0; i < source.Count; i++)
try{ results.Add(Fetch(source[i])); }
catch(Exception ex){ results.Add(new MyClass("poof!")); }
...
public MyClass Fetch(Object source){ ... }
并希望将其重新制作成LINQ,如何管理 try-catch ?如果我把它放在下面的表达式中,它就不会让我感到困惑。我的建议是迁移捕获方法,但我不确定它是多么优化/推荐。可以说一下还是取决于场景的具体情况?
IEnumerable<String> strings = source.Select(e => Fetch(e));
public MyClass Fetch(Object source){ try{ ... } catch(){ ... } }
像这样的伪代码很酷。我正在考虑方法.First()
,它是更有效的兄弟.FirstOrDefault()
,但有额外的容量。
IEnumerable<String> strings = source.Select(e => Fetch(e)).Excepted(...);
我离开了吗?
答案 0 :(得分:2)
最好的办法是将try / catch
块移动到单独的方法中,并将该方法用作选择器。
public MyClass FetchOrDefault(object source){
try {
return Fetch(source);
} catch (Exception ex) {
return new MyClass("poof");
}
}
// Method call syntax
var e = source.Select(x => x.FetchOrDefault(x));
// LINQ syntax
var e = from x in source select FetchOrDefault(x);
答案 1 :(得分:0)
您将获得与原始代码相同的行为
List<String> results = source.Select(e => { try
{
return Fetch(e);
}
catch(Exception)
{
return MyClass("poof");
}
}).ToList();
但我认为你应该重新考虑使用try / catch这种方式。它具有严重的性能成本,并非旨在处理非特殊情况。如果可以获取e
并执行类似
List<String> results = source.Where(e => IsFetchable(e))
.Select(e => Fetch(e))
.ToList();
答案 2 :(得分:0)
最简单的解决方案就是做你已经做过的事情 即你可以包括代码块。
IEnumerable<String> strings = source.Select(e =>
{
try
{
return Fetch(e);
}
catch
{
return new MyClass("poof");
}
}
);
答案 3 :(得分:0)
我认为您无法创建Excepted
类,但您可以使用两个选择器创建Select
方法,其中一个用于错误情况:
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source,
Func<TSource, TResult> selector, Func<TSource, TResult> secondarySelector)
{
foreach (var item in source)
{
TResult nextValue;
try
{
nextValue = selector(item);
}
catch
{
nextValue = secondarySelector(item);
}
yield return nextValue;
}
}
然后它会允许你这样做:
var results = source.Select(item => Fetch(item)
, item => new MyClass("poof!"))
.ToList();
您的辅助选择器也可以将异常作为参数,如果这是合适的。