如果声明 - '或'但不是'和'

Wil*_*son 7 c# if-statement

在C Sharp中,如何设置if语句来检查其中一个条件是否为真?它必须只是其中一个条件,如果为0或者两个或更多,则if应为false.

jas*_*son 9

你可以写一个帮助方法.这样做的好处是它可以短路,只需要根据需要进行精确评估,

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)


Dou*_*las 5

您可以使用将布尔值组合成一个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)

用于测试的样本数据(可以在每个上设置断点falsetrue遵循评估):

IEnumerable<Func<bool>> conditions = new Func<bool>[] 
{ 
    () => 
        false,
    () => 
        true,
    () => 
        false,
    () => 
        false,
};
Run Code Online (Sandbox Code Playgroud)


Amy*_*y B 5

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)