我有这个功能:
bool TrySomething(IEnumerable<T> items, out List<T> listOfProblemItems)
{
//...
return listOfProblemItems != null && listOfProblemItems.Count > 0;
}
现在的工作方式与您对“TrySomething”模式(例如 TryParse
)的期望相反:
如果出现错误,它返回 true
(以指示 out
参数已填充信息)。这样我就可以这样调用它:
if(TrySomething(items, out problemItems))
{
//handle problems
//"but.. it returned 'true'! Why are there problems? I'm confused."
}
如果有问题返回true
是不直观的,但是如果我把它改成false
,那么out
参数就会被填充带有关于 false
的信息,从而打破了“TrySomething”模式。
if(TrySomething(items, out problemItems) == false)
{
//handle problems
//"the 'out' parameter is used? but it returned false! I'm confused."
}
这不是我抛出异常的替代方案,因为这是一个高性能的部分,我需要一个明确定义的列表,列出哪些项目无论如何都失败了。
我可以让它返回问题列表并将其命名为TrySomethingAndReturnAnyProblems
,但是这个名字很难看并且调用代码必须检查返回的列表是否为null和计数,我宁愿在函数中完成它,因为无论如何它总是必须完成。
List<T> problems = TrySomethingAndReturnAnyProblems(items);
if(problems != null && problems.Count > 0)
{
//ugly and introduces duplicate code every time the function is used.
}
如何在保持“TrySomething”模式的简洁性的同时将其变成可读的、自文档化的函数定义?
最佳答案
如何编写一个扩展方法来简单地过滤掉有问题的项目?这样,您只能取回没问题的元素,例如:
public static IEnumerable<T> ExceptProblematic(this IEnumerable<T> items)
{
foreach (var item in items)
{
if (!IsProblematic(item))
yield return item;
}
}
这样你就可以像这样使用它:
var validItems = items.ExceptProblematic();
或者,您可以编写一个查询以仅返回有问题的项目,然后进行另一个查询以将其过滤掉,例如:
var problemItems = items.Where(item => IsProblematic(item));
var validItems = items.Except(problemItems);
然后相应地处理问题项:
if (problemItems.Any())
{
// handle problem items
}
关于c# - 如何重写 bool TrySomething(List<T> items, out List<T> itemsThatFailed),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20096354/