如果您必须使用 Linq,这应该可以工作:
if (item.States.Any(state => state == State.Important) && item.States.Any(state => state == State.Updated))
否则Contains()
就像@ElRonnoco 说的那样使用。
(但是,如果您的州是旗帜(2 的幂),那么这个答案会略有不同。)
这种方法的问题在于,如果没有设置任何状态,它会完全迭代集合两次。如果这种情况经常发生,它会比它可能的慢。
您可以在没有 linq 的情况下一次性解决它,如下所示:
bool isUpdated = false;
bool isImportant = false;
foreach (var state in item.States)
{
if (state == State.Important)
isImportant = true;
else if (state == State.Updated)
isUpdated = true;
if (isImportant && isUpdated)
break;
}
if (isImportant && isUpdated)
{
// ...
}
这不太可能成为问题,除非您有非常大的列表,而这些列表通常没有设置任何一个目标状态,因此您可能最好还是使用 El Ronnoco 的解决方案。
如果你有很多状态要处理,你可以通过编写一个扩展方法来简化事情,如下所示:
public static class EnumerableExt
{
public static bool AllPredicatesTrueOverall<T>(this IEnumerable<T> self, params Predicate<T>[] predicates)
{
bool[] results = new bool[predicates.Length];
foreach (var item in self)
{
for (int i = 0; i < predicates.Length; ++i)
if (predicates[i](item))
results[i] = true;
if (results.All(state => state))
return true;
}
return false;
}
我很难想出这个名字。true
如果对于每个谓词,序列中至少有一项谓词为真,它将返回。但这对于方法名称来说有点长......;)
那么您的示例将变为:
if (item.States.AllPredicatesTrueOverall(s => s == State.Important, s => s == State.Updated))
下面是一些使用它的示例代码:
enum State
{
Unknown,
Important,
Updated,
Deleted,
Other
}
void run()
{
IEnumerable<State> test1 = new[]
{
State.Important,
State.Updated,
State.Other,
State.Unknown
};
if (test1.AllPredicatesTrueOverall(s => s == State.Important, s => s == State.Updated))
Console.WriteLine("test1 passes.");
else
Console.WriteLine("test1 fails.");
IEnumerable<State> test2 = new[]
{
State.Important,
State.Other,
State.Other,
State.Unknown
};
if (test2.AllPredicatesTrueOverall(s => s == State.Important, s => s == State.Updated))
Console.WriteLine("test2 passes.");
else
Console.WriteLine("test2 fails.");
// And to show how you can use any number of predicates:
bool result = test1.AllPredicatesTrueOverall
(
state => state == State.Important,
state => state == State.Updated,
state => state == State.Other,
state => state == State.Deleted
);
}
但也许最简单的方法是为IEnumerable<State>
(如果您只需要担心一个状态枚举)编写一个扩展方法:
public static class EnumerableStateExt
{
public static bool AllStatesSet(this IEnumerable<State> self, params State[] states)
{
bool[] results = new bool[states.Length];
foreach (var item in self)
{
for (int i = 0; i < states.Length; ++i)
if (item == states[i])
results[i] = true;
if (results.All(state => state))
return true;
}
return false;
}
}
然后您的原始代码将变为:
if (item.States.AllStatesSet(State.Important, State.Updated))
您可以轻松指定更多状态:
if (item.States.AllStatesSet(State.Important, State.Updated, State.Deleted))