C# while(k>;=0&;arr[k]>;0)安全吗?

C# while(k>;=0&;arr[k]>;0)安全吗?,c#,coding-style,C#,Coding Style,是 安全吗 当k在范围内且arr[k]>0时,它会循环。但我不知道这是否是一个好的编码实践。我知道如果我们这样做 while (k >= 0 && arr[k] > 0) 这将是一场灾难。是的,这是一个很好的做法。事实上,这就是短路&&操作符被发明的部分原因。运算符从左到右计算其子表达式,并在发现错误的子表达式时停止。这正是你想要的;&&运算符允许您在一行中表示这一点。短路是安全的。如果k小于零,它将不会索引到arr while循环的主体可能不会正确地减小k,从而

安全吗

当k在范围内且arr[k]>0时,它会循环。但我不知道这是否是一个好的编码实践。我知道如果我们这样做

while (k >= 0 && arr[k] > 0) 

这将是一场灾难。

是的,这是一个很好的做法。事实上,这就是短路
&&
操作符被发明的部分原因。运算符从左到右计算其子表达式,并在发现错误的子表达式时停止。这正是你想要的;
&&
运算符允许您在一行中表示这一点。

短路是安全的。如果
k
小于零,它将不会索引到
arr


while循环的主体可能不会正确地减小
k
,从而导致无限循环,这可能不安全。或者,如果
k
超出
arr
的界限,则可能不安全。

您还应注意数组大小:

while (arr[k] > 0 && k >= 0) 
while(k>=0&&k0)

将是更安全的代码。

关于表达式:

而(k>=0&&arr[k]>0{…}

不,它不安全。

表达式
k>=0&&arr[k]>0
是安全的,它确保只使用
arr[k]
的正指数(因为
和&
缩短了
k<0
的值,并且在这些情况下不计算第二个操作数
arr[k]>0

但是请注意,不能保证索引超出范围(例如,
k>=arr.length
)-并且arr也可以是
null
。因此,您可以获得
索引自动失效异常
NullReferenceException
——如果未经处理,您的应用程序将中断

要避免这种情况,请使用

while (k >= 0 && k < arr.length && arr[k] > 0) 
请注意,因为您不是从0开始的,所以我跳过了初始化
var k=0
,我假设您是在上面的源代码之外的某个地方完成的


除此之外,还有一些附加信息-如果您想了解有关逻辑运算符和副作用的一些有趣细节,请继续阅读

C/C++/C#中,了解
&
&
之间的区别非常重要:
&
以“位”方式计算整个表达式,而
&
如果结果已经清楚,则停止计算(如果表达式的任何部分为
,则逻辑
不能为
;如果表达式的任何部分为
,则逻辑
不能为

在某些情况下但是,您也需要非快捷方式版本
&
。假设您希望将字符串数组转换为整数数组,并且希望转换可以转换的每个值,即使某些值无法转换为整数(其他值应保持为0)-如以下示例所示:

if (k >=0 && arr != null) 
    for (; var k=0; k<arr.Length && arr[k] > 0; k++) { ... }
这不是我们所期望的,因为10和11也是有效的整数,应该进行转换,相反,我们得到了0和0

为了得到我们期望的结果,即

4 2 0 0 0 0 
我们需要将
&
替换为
&
,如下所示:

4 2 0 0 10 11 
这里有什么区别?

如果您在上面的语句中使用了
&&
,那么只要bCheck的计算结果为false,就会执行快捷方式-这通常是正确的,因为这样我们就不必再检查表达式,因为它不可能被计算为true

但是,由于我们有了快捷方式,
int.TryParse
不再被调用,因此值不会从函数中传递出去-无论
sArr[i]
中包含的值如何,循环中的所有后续调用都将计算为0


这是我们在这里遇到的意外副作用,可以通过强制计算每个表达式(通过使用
&
)来修复.

除非您说明如何更改
k
,否则无法说明它是否安全。此外,在多线程场景中,答案会有很大差异。在这种格式下,您不能使用for循环吗?for(int k=20;arr.Length>k&&arr[k]>0;k--)也可以考虑可读性。它可以为你节省几行代码,但是一个更年轻的开发人员花了多少时间来弄清楚这是怎么做的……唯一安全可靠的是,如果第一个条件,<代码> k>=0 < /代码>评估为<代码> false <代码>,那么就不会尝试评估第二个条件。因此,
arr[k]
不会因为负的
k
而爆炸。当然,它可能会因为其他原因出错。顺便说一句,您是否考虑过LINQ?声明式地处理集合往往不那么麻烦。
SkipWhile
Take
可能会有帮助:
4 2 0 0 0 0 
4 2 0 0 10 11 
bCheck = bCheck & int.TryParse(sArr[i], out value);