简化LINQ查询
我需要一些简化LINQ查询的帮助。条件如下:简化LINQ查询
- 我需要将
bool IsValid(string expression)
应用于给定序列的每个元素。 - 如果
IsValid
对所有元素均为true,则返回true
。 - 如果
IsValid
对于任何元素均为false,则返回false
。 - 如果序列为空或空,也返回
false
。
我想出了查询
try
{
(sequence.DefaultIfEmpty().Where(item => !IsValid(item).Count() == 0)
}
catch (ArgumentNullException)
{
return false;
}
的一点是,IsValid(null)
抛出一个ArgumentNullException
这是由catch
块捕获。但是,我认为这太棘手。没有任何方法可以简化方法而不依赖于这个事实?
为什么不:
return sequence.Any() && sequence.All(item => IsValid(item));
如果你担心单独sequence.Any()
检查,结果在一个ReSharper的警告(这是必要的与你只能遍历一次像一个网络,数据库等任何序列)你可以写,做检查和迭代序列只有一次的通用扩展方法:
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));
您应该能够使用:
return sequence.Any() && sequence.All(item => IsValid(item));
是的,你是对的!但是,这引发了ReSharper的“可能的IEnumerable多重枚举”警告,我想避免这种警告。 – User
@用户:在这种情况下,为了让您的空/空检查正常,循环可能是最好的选择... –
看起来像一个同时回答给我。 –
我不知道它会很容易做到这一点很好只是一个单一的通行证。我相信这是可行,但我不确定它会不错。然而,它的死很容易编写自己的扩展方法:
(编辑:我明白了,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);
是的,你是对的!但是,这引发了ReSharper的“可能的IEnumerable多重枚举”警告,我想避免这种警告。 – User
DefaultIfEmpty将只返回一个空项目 - 这里的目的是什么? –
是刚刚修复那部分,没有看到空集合的要求 – BrokenGlass