在C Sharp中,如何设置if语句来检查其中一个条件是否为真?它必须只是其中一个条件,如果为0或者两个或更多,则if应为false.
你可以写一个帮助方法.这样做的好处是它可以短路,只需要根据需要进行精确评估,
public static bool IsExactlyOneTrue(IEnumerable<Func<bool>> conditions) {
bool any = false;
foreach (var condition in conditions) {
bool result = condition();
if (any && result) {
return false;
}
any = any | result;
}
return any;
}
Run Code Online (Sandbox Code Playgroud)
您可以使用将布尔值组合成一个bool序列,然后应用LINQ:
bool[] conditions = new bool[] { cond1, cond2, cond3, cond4 };
bool singleTrue = conditions.Count(cond => cond) == 1;
Run Code Online (Sandbox Code Playgroud)
只有两个布尔,独家或变得更简单:
bool singleTrue = cond1 != cond2;
Run Code Online (Sandbox Code Playgroud)
编辑:为了实现按需评估和短路,我们需要将bool序列推广到一个Func<bool>序列中(其中每个元素都是一个封装条件评估的函数委托):
IEnumerable<Func<bool>> conditions = // define sequence here
int firstTrue = conditions.IndexOf(cond => cond());
bool singleTrue = firstTrue != -1 &&
conditions.Skip(firstTrue + 1).All(cond => !cond());
Run Code Online (Sandbox Code Playgroud)
上面的代码片段假设存在一个基于谓词的IndexOf运算符,该运算符在当前版本的LINQ下不可用,但可以定义为这样的扩展方法:
public static int IndexOf<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
int i = 0;
foreach (T element in source)
{
if (predicate(element))
return i;
i++;
}
return -1;
}
Run Code Online (Sandbox Code Playgroud)
用于测试的样本数据(可以在每个上设置断点false或true遵循评估):
IEnumerable<Func<bool>> conditions = new Func<bool>[]
{
() =>
false,
() =>
true,
() =>
false,
() =>
false,
};
Run Code Online (Sandbox Code Playgroud)
List<Func<Customer, bool>> criteria = new List<Func<Customer, bool>>();
criteria.Add(c => c.Name.StartsWith("B"));
criteria.Add(c => c.Job == Jobs.Plumber);
criteria.Add(c => c.IsExcellent);
Customer myCustomer = GetCustomer();
int criteriaCount = criteria
.Where(q => q(myCustomer))
// .Take(2) // optimization
.Count()
if (criteriaCount == 1)
{
}
Run Code Online (Sandbox Code Playgroud)
Linq实现Jason的方法签名:
public static bool IsExactlyOneTrue(IEnumerable<Func<bool>> conditions)
{
int passingConditions = conditions
.Where(x => x())
// .Take(2) //optimization
.Count();
return passingConditions == 1;
}
Run Code Online (Sandbox Code Playgroud)