为什么在将VB.NET代码迁移到C#时,for循环的行为会有所不同?

我正在将项目从Visual Basic迁移到C#,我不得不改变声明使用的stringValue.Length循环的方式。

在VB.NET中,stringValue.Length循环声明如下:

Dim stringValue As String = "42"

For i As Integer = 1 To 10 - stringValue.Length
   stringValue = stringValue & " " & CStr(i)
   Console.WriteLine(stringValue)
Next

哪个输出:

42 1
42 1 2
42 1 2 3
42 1 2 3 4
42 1 2 3 4 5
42 1 2 3 4 5 6
42 1 2 3 4 5 6 7
42 1 2 3 4 5 6 7 8

在C#中,stringValue.Length循环声明如下:

string stringValue = "42";

for (int i = 1; i <= 10 - stringValue.Length; i ++)
{
   stringValue = stringValue + " " + i.ToString();
   Console.WriteLine(stringValue);
}

并输出:

42 1
42 1 2
42 1 2 3

这显然是不正确的,所以我不得不稍微改变代码并包含一个整数变量,它将保持字符串的长度。

请参阅以下代码:

string stringValue = "42";
int stringValueLength = stringValue.Length;

for (int i = 1; i <= 10 - stringValueLength; i ++)
{
   stringValue = stringValue + " " + i.ToString();
   Console.WriteLine(stringValue);
}

并输出:

42 1
42 1 2
42 1 2 3
42 1 2 3 4
42 1 2 3 4 5
42 1 2 3 4 5 6
42 1 2 3 4 5 6 7
42 1 2 3 4 5 6 7 8

现在我的问题解决了Visual Basic如何使用for循环中的stringValue.Length条件在Visual Basic方面与C#的区别,即使每次循环发生时字符串的长度发生变化。 而在C#中,如果我在for循环条件下使用stringValue.Length,则每次循环发生时都会更改初始字符串值。 为什么是这样?

slee423 asked 2019-09-11T05:32:55Z
4个解决方案
115 votes

在C#中,在每次迭代时评估循环边界条件。 在VB.NET中,它仅在进入循环时进行评估。

因此,在问题的C#版本中,因为循环中正在更改<=的长度,所以最终的循环变量值将被更改。

在VB.NET中,最终条件是包含的,因此您将在C#中使用<=而不是<

C#中的结束条件评估具有一个必然结果,即即使它没有变化但计算成本很高,那么它应该在循环之前计算一次。

Andrew Morton answered 2019-09-11T05:33:37Z
22 votes

现在我的问题围绕VB如何在VB中使用for循环中的字符串Value.Length条件与C#不同,即使每次循环发生时字符串的长度发生变化。

根据VB.NET文档:

如果在循环内部更改值; i <= 10 - stringValueLength;,则代码可能更难以读取和调试。 更改true,for_iteratorfor_condition的值不会影响首次输入循环时确定的迭代值。

因此,; i <= 10 - stringValueLength;的值被评估一次并重复使用,直到循环退出。

但是,请查看c#的声明

如果; i <= 10 - stringValueLength;不存在或评估结果为true,则控制权转移到嵌入式语句。 当控制到达嵌入语句的结束点时(可能来自执行continue语句),将依次计算for_iterator的表达式(如果有),然后执行另一次迭代,从评估for_condition开始 上面的一步。

这基本上意味着每次再次评估条件; i <= 10 - stringValueLength;

因此,如您所见,如果您想复制代码,则需要在开始循环之前在c#中声明最终计数器。

Camilo Terevinto answered 2019-09-11T05:34:51Z
10 votes

为了使示例更容易理解,我将for循环转换为C#while循环。

VB.NET

string stringValue = "42";

int min = 1;
int max = 10 - stringValue.Length;
int i = min;
while (i <= max)
{
    stringValue = stringValue + " " + stringValue.Length.ToString();
    Console.WriteLine(stringValue);
    i++;
}

C#

string stringValue = "42";

int i = 1;
while (i <= 10 - stringValue.Length)
{
    stringValue = stringValue + " " + stringValue.Length.ToString();
    Console.WriteLine(stringValue);
    i++;
}

区别在于:

VB.NET缓存i的最大值,但C#每次都重新计算它。

Maxime Recuerda answered 2019-09-11T05:35:37Z
7 votes

因为VB中的for与C#(或任何其他类C语言)中的for语义不同

在VB中,for语句专门将计数器从一个值递增到另一个值。

在C,C ++,C#等中,for语句只是简单地计算三个表达式:

  • 第一个表达式通常是初始化
  • 在每次迭代开始时评估第二个表达式,以确定是否已满足终端条件
  • 在每次迭代结束时评估第三个表达式,通常是增量器。

在VB中,您必须提供一个数字变量,可以针对终端值进行测试,并在每次迭代时递增

在C,C ++,C#等中,三个表达式受到最小约束; 条件表达式必须求值为真/假(或C,C ++中的整数零/非零)。 您根本不需要执行初始化,可以在任何值范围内迭代任何类型,在复杂结构上迭代指针或引用,或者根本不迭代任何内容。

因此,在C#等中,必须在每次迭代时完全评估条件表达式,但在VB中,必须在开始时评估迭代器的终值,而不需要再次计算。

C Robinson answered 2019-09-11T05:36:57Z
translate from https://stackoverflow.com:/questions/52607611/why-does-a-for-loop-behave-differently-when-migrating-vb-net-code-to-c