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

时间:2018-10-02 11:38:56

标签: c# vb.net loops for-loop

我正在将项目从Visual Basic迁移到C#,并且不得不更改声明使用的for循环的方式。

在VB.NET中,for循环在下面声明:

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#中,for循环在下面声明:

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

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

4 个答案:

答案 0 :(得分:115)

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

因此,在所涉及的C#版本中,由于stringValue的长度在循环中被更改,因此最终循环变量值将被更改。

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

C#中的最终条件评估具有一个推论,即即使它没有变化,但计算起来很昂贵,但也应该在循环之前进行一次计算。

答案 1 :(得分:22)

  

现在我的问题解决了使用forValue循环中的stringValue.Length条件在VB方面VB与C#有何不同,即使每次循环发生时,字符串的长度也会改变。

根据VB.NET文档:

  

如果在循环内更改counter的值,则代码可能更难以阅读和调试。更改startendstep的值不会影响首次进入循环时确定的迭代值。

因此,To 10 - stringValue.Length的值将被评估一次并重复使用,直到循环退出。

但是,请看c#'s for statement

  

如果不存在for_condition或评估得出true,则控制权将转移到嵌入语句。当且如果控制到达嵌入式语句的终点(可能是从执行continue语句开始),则for_iterator的表达式(如果有)将按顺序求值,然后从评估开始执行另一个迭代以上步骤中for_condition的值。

这基本上意味着条件; i <= 10 - stringValueLength;每次都会被重新评估。

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

答案 2 :(得分:10)

为了使示例更易于理解,我将两个 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#每次都会重新计算。

答案 3 :(得分:7)

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

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

在C,C ++,C#等环境中,for语句仅计算三个表达式:

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

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

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

因此,在C#等环境中,必须在每次迭代中对条件表达式进行完全求值,但在VB中,迭代器的终值必须在开始时求值,而不必再次求值。