判断值是否不同

Determine if values are different

假设我有 4 个变量

bool value1 = false;
bool value2 = false;
bool value3 = true;
bool value4 = false;

而且它们都没有相同的值(都是真的 || 都是假的)

我找到了 2 种方法,反正其中 none 看起来很容易理解。

bool areDifferent = !(value1 == value2 == value3 == value4);

bool areDifferent = new[] { value1, value2, value3, value4 }.Distinct().Count() > 1;

问题:是否有其他方法,在可读性/可理解性方面更好?

尽管就个人而言,我更喜欢您的第一种方法,但以下方法也适用。

bool value1 = false;
bool value2 = false;
bool value3 = true;
bool value4 = false;

var values = new[] { value1, value2, value3, value4 };

bool areDifferent = values.Any(v => v) && values.Any(v => !v);

为了可读性和理解,我会交换逻辑。当您检查值是否不同时,并不清楚 - 所有值都应该不同(考虑整数值 1、2、3),或者值可能相等,但至少有一个不同的值(1、2、1)?当您检查所有值是否相等时,它总是很清楚。

我会将此逻辑提取到命名良好的方法中(如果需要,您甚至可以将其设为通用):

public static bool AllEqual(params bool[] values)
{
    if (values.Length == 0)
       return true;

    var first = values[0];
    for (int i = 1; i < values.Length; i++)
        if (values[i] != first)
            return false;

    return true;
}

和用法

var notAllEqual = !AllEqual(value1, value2, value3, value4);

使用声明式方法,您的代码描述您正在做什么,而不是告诉如何和让 reader 自行理解是什么。


更新:如果你总是处理四个布尔值,检查它们是否不相等的最简单方法是

(value1 ^ value2) || (value2 ^ value3) || (value3 ^ value4)

但是就可读性而言,任何命令式的方式都比声明式的差

你可以把位组合起来检查

int value = (value1 ? 8 : 0) |
            (value2 ? 4 : 0) |
            (value3 ? 2 : 0) |
            (value4 ? 1 : 0);
return value != 0 && value != 15;

为了便于理解,我们可以创建一个方法并使用 if 块。

public bool areDifferent(bool value1, bool value2, bool value3, bool value4)
{
    if(value1 == value2)
        if(value2 == value3)
            if(value3 == value4)
                return false;
                    
    return true;
}

也许 Linq 的声明性足够了?

var values = new[] { false, false, true, false };
bool notAllEqual = values.Any(x => x != values.First());

或者:

var values = new[] { false, false, true, false };
bool allEqual = values.All(x => x == values.First());
if (!allEqual)
{
     // They are different
}

你说你想检查你的元素是否不

all are true || all are false

给定一个列表 var values = new List<bool> { value1, value2, value3, value4 }; 这些元素,代码中最接近的表示形式是:

var areDifferent = !(values.All(v => v == true) || values.All(v => v == false));

虽然在可读性方面,我更喜欢:

var areEqual = values.All(v => v == true) || values.All(v => v == false);

稍后检查:

 if (!areEqual)
 {
     // Do something
 }

但这只是个人喜好。

我觉得这有点代码味道,您可能需要重构代码而不是寻找更好的方式来显示布尔值。

如果不提供实际代码,您将始终得到假设而不是答案。

无论如何,关于您的具体问题,您可以创建一个 public static class 并将其用作结果测试器来验证您代码中的所有类型的结果。这样,您可以重复使用它,而且可读性也会更好。

例如:

public static class Validate
{
    public static bool AreEqual(params bool[] values) => AreTrue(values) || AreFalse(values);
    
    public static bool AreTrue(params bool[] values) => values.All(x => x == true);
    
    public static bool AreFalse(params bool[] values) => values.All(x => x == false);
}

然后像这样使用它:

bool value1 = false;
bool value2 = false;
bool value3 = true;
bool value4 = false;

if(Validate.AreEqual(value1 , value2 , value3 , value4))
{
    // do something
}

通用方法:

static bool AreDifferent(params bool[] values)
{
    var tmp = values.Select((value, index) => value ? 1 << index : 0).Aggregate((i, j) => i | j);
    return tmp != 0 && tmp != (1 << values.Length) - 1;
}