You can use the layout of your logic gates in a bool sequence, and then apply LINQ:
bool[] conditions = new bool[] { cond1, cond2, cond3, cond4 }; bool singleTrue = conditions.Count(cond => cond) == 1;
Only for two logical objects, exclusive or significantly simplified:
bool singleTrue = cond1 != cond2;
Change In order to achieve an on-demand evaluation and short circuit, we need to push our bool sequence to the Func<bool> sequence (where each element is a function delegate encapsulating the condition estimate):
IEnumerable<Func<bool>> conditions = // define sequence here int firstTrue = conditions.IndexOf(cond => cond()); bool singleTrue = firstTrue != -1 && conditions.Skip(firstTrue + 1).All(cond => !cond());
The above snippet assumes the existence of a predicate-based IndexOf operator, which is not available in the current version of LINQ, but can be defined as an extension method, for example:
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; }
Example data for testing (a breakpoint can be set for each false or true for evaluation):
IEnumerable<Func<bool>> conditions = new Func<bool>[] { () => false, () => true, () => false, () => false, };
Douglas
source share