我需要一点帮助来简化LINQ查询。条件如下:
bool IsValid(string expression)
应用于给定序列的每个元素。IsValid
对所有元素都为真,请返回true
。IsValid
为false,请返回false
。false
。我提出的查询是
try
{
(sequence.DefaultIfEmpty().Where(item => !IsValid(item).Count() == 0)
}
catch (ArgumentNullException)
{
return false;
}
重点是IsValid(null)
会抛出ArgumentNullException
阻止的catch
。但是,我认为这太棘手了。有什么方法可以简化方法而不依赖于这个事实吗?
答案 0 :(得分:6)
为什么不:
return sequence.Any() && sequence.All(item => IsValid(item));
如果您担心导致Resharper警告的单独sequence.Any()
检查(由任何序列保证,您只能像网络,数据库等那样迭代一次),您可以编写一个通用扩展名执行检查并仅迭代序列一次的方法:
public static bool NotEmptyAndValid<T>(this IEnumerable<T> source,
Func<T, bool> predicate)
{
bool hasItem = false;
foreach(var item in source)
{
hasItem = true;
if(!predicate(item))
return false;
}
return hasItem;
}
然后你可以这样做:
return sequence.NotEmptyAndValid( x => IsValid(x));
答案 1 :(得分:3)
你应该可以使用:
return sequence.Any() && sequence.All(item => IsValid(item));
答案 2 :(得分:1)
我不确定只需一次通过即可轻松完成很好。我确定它是可行的,但我不确定它会不会很好。但是,编写自己的扩展方法很容易:
(编辑:我看到BrokenGlass现在用foreach
编写了一个类似的方法。我将把它作为替代方法。)
public static boolean AllAndNotEmpty<T>(this IEnumerable<T> source,
Func<T, bool> predicate)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
return false;
}
do
{
if (!predicate(iterator.Current))
{
return false;
}
} while (iterator.MoveNext());
}
return true;
}
然后:
var result = items.AllAndNotEmpty(IsValid);