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

sle*_*423 86 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
Run Code Online (Sandbox Code Playgroud)

哪个输出:

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
Run Code Online (Sandbox Code Playgroud)

在C#中,for循环声明如下:

string stringValue = "42";

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

并输出:

42 1
42 1 2
42 1 2 3
Run Code Online (Sandbox Code Playgroud)

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

请参阅以下代码:

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

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

并输出:

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
Run Code Online (Sandbox Code Playgroud)

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

And*_*ton 115

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

所以,在问题的C#版本中,因为stringValue循环中的长度被改变,所以最终的循环变量值将被改变.

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

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


SO *_*ood 22

现在我的问题解决了VB在VB中使用for循环中的stringValue.Length条件与C#的区别,即使每次循环发生时,字符串的长度也会发生变化.

根据VB.NET文档:

如果counter在循环内更改while 的值,则代码可能更难以读取和调试.改变的值start,endstep不影响被当首次进入循环确定的迭代值.

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

但是,请查看c#的声明

如果for_condition不存在或评估结果true,则控制转移到嵌入语句.当控制到达嵌入语句的结束点时(可能来自执行continue语句),for_iterator将按顺序计算(如果有)的表达式,然后执行另一次迭代,从for_condition步骤的评估开始以上.

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

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


Max*_*rda 9

为了使示例更容易理解,我将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++;
}
Run Code Online (Sandbox Code Playgroud)

C#

string stringValue = "42";

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

区别在于:

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

  • 它让我在开始时理解了"for循环",我认为它们更容易理解.这就是为什么我'在'while循环'中'翻译'示例,以帮助理解. (10认同)
  • 您不需要将循环转换为while (2认同)

C R*_*son 7

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

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

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

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

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

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

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