C# 仅检查数组或列表中的特定布尔值

C# 仅检查数组或列表中的特定布尔值,c#,boolean,C#,Boolean,我想学习如何做到这一点的不同方法 当0和3为true而其余为false时,代码会执行某些操作 有没有一种“更干净”或“更高效”的方法可以做到这一点?您可以在Unity中使用NamespaceSystem.Linq来做到这一点 if (boolThing[0] == true && boolThing[2] == true && !boolThing[1] && !boolThing[3]

我想学习如何做到这一点的不同方法

当0和3为true而其余为false时,代码会执行某些操作


有没有一种“更干净”或“更高效”的方法可以做到这一点?

您可以在Unity中使用NamespaceSystem.Linq来做到这一点

 if (boolThing[0] == true 
        && boolThing[2] == true 
        && !boolThing[1] 
        && !boolThing[3] 
        && !boolThing[4])
    {
        Debug.Log("Hey");
    }

您可以将变量放入适当的列表中,然后测试每个
列表
是否只包含特定值的元素(
true
false
):

List thingstedfortrue=新列表{boolThing[0],boolThing[1],boolThing[2]};
List thingstedforfalse=新列表{boolThing[3],boolThing[4],boolThing[5]};
if(thingstedfortrue.All(thing=>thing==true)和&thingstedforfalse.All(thing=>thing==false)
{
//所有值都已传递
}
您不需要
if(boolThing[0]==true)
。您可以使用`if(boolThing[0]))

还可以使用二进制运算符一起计算多个布尔值

List<bool> thingsTestedForTrue = new List<bool> { boolThing[0], boolThing[1], boolThing[2] };
List<bool> thingsTestedForFalse = new List<bool> { boolThing[3], boolThing[4], boolThing[5] };

if(thingsTestedForTrue.All(thing => thing == true) && thingsTestedForFalse.All(thing => thing == false) 
{
    // All values passed
}
您可以使用
位数组
轻松处理布尔值集合,这样会更加高效

最有效的方法是使用数字类型

最简单的方法是使用带有标志的枚举。可以使用二进制运算符设置或清除枚举的标志

if((bools[0]&bools[3]) && !(bools[1]|bools[2]|bools[4]|bools[5])
在代码中,您现在可以检查:

MyBoolFlag myFlag = MyBoolFlag.Bool0|MyBoolFlag.Bool1|MyBoolFlag.Bool3;
可以为各种条件定义常量

if(myFlag == MyBoolFlag.Bool0|MyBoolFlag.Bool3)
{

}
然后检查:

const MyBoolFlag myCondition1 = MyBoolFlag.Bool0|MyBoolFlag.Bool3;
您还可以做更多的工作,直接使用诸如byte和int之类的本机类型

可以使用单个字节将8个布尔值保存为标志掩码,每个值表示2的幂。uint32可以保存32个布尔值,uint64可以保存64个布尔值

这有一个巨大的性能提升,因为布尔值存储为uint32,这意味着它使用4字节的数据,当使用bits ask布尔标志时,可以在uint32中打包32个布尔值

程序的执行速度也会更快,因为CPU使用本机字在单个操作中计算myFlag==myCondition1。否则,将查找布尔值放入数组并进行比较需要许多指令。Net还将进行一些健全性检查,确保数组不为null,索引不超出范围,然后需要移动指针来查找这些值

为了方便起见,您可以从布尔数组中创建一个位数组,然后使用它初始化一个设置了相应标志的数值类型数组

例如:

if(myFlag == myCondition1)
{

}
这一点是,如果布尔值[0]=真,布尔值[3]为真,则“值”将为9

因此,您的代码应该是:

bool[] bools = new bool[] { true, false, false, true, false, false };
BitArray bitArray = new BitArray(new bool[] { true, false, false, true, false, false });
int[] array = new int[1];
bitArray.CopyTo(array, 0);
int value = array[0];
您还可以创建常量掩码来检查不同的数值,以检查数值中是否设置了不同的位,或者使用二进制操作来操作这些位

if(value==9) // bools[0]&bools[1]==true;
通过使用二进制操作设置数值,可以获得更高的效率

if(value==9) // bools[0]&bools[1]==true;

uint32 myFlag=1 |(1
boolThing[0]==true
只能是
boolThing[0]
==true
是多余的。在您的示例中
(bools[0]&bools[3])&!(bools[1]| bools[2]| bools[4]| bools[5])
一开始时,不需要“单一”
&
运算符。这是浪费,只需在那里使用
&
&
即可。
&
将起作用,但需要三个操作来评估第一组是否为真,但
&
将需要一个。使用
&
第一个操作检查bools[0]是否为真,第二个检查bools[1]是true,第三个是副题中的
&
运算符。使用
&
二进制操作将布尔[0]和布尔[1]组合在一起将其转换为单个结果,然后评估其是否为真。您可以编写此代码并查看VS中的反汇编以进行验证。由于使用了
|
,下半年还会有更多的JMP。您可以使用这两种方法运行数百万次循环以进行验证。有趣的是,在用于验证的一百万次循环中,有
bools的内容吗e> 每次都一样?如果在括号内进行,为什么不在“final”中间操作中使用
&
?短路和非短路的混合看起来很奇怪。例如,如果我取出子表达式
bools[1]| bools[2]| bools[4]| bools[5])
,则必须检查所有数组项,即使
bools[1]
已经是
true
。但是检查数组条目的速度非常快,因此这是一种特殊情况。
|
链需要多长时间才能使
|
更有效?您是对的,整个表达式可能是一个二进制操作。关键是,当您有一个使用二进制操作执行多个语句的代码块时,它通常会比使用&&或| |的语句执行得更快,即使它们短路。原因是短路操作实际上是作为单独的IF语句进行计算的,在汇编中,IF语句变成了跳转语句。循环中的跳转语句非常可怕。这就是为什么程序员会展开循环,因为循环控件本身是一个跳转语句,它会减慢代码的执行速度。在索引查找操作之间放置if/jump语句时,问题更严重,因为在.Net中,除非对代码进行优化,否则不会像在本机代码中那样直接查找指向数组的指针。
if(value==9) // bools[0]&bools[1]==true;
uint32 myFlag= 1|(1<<3);