1. ホーム
  2. c#

[解決済み] VB.NETのコードをC#に移行すると、なぜforループの動作が異なるのですか?

2023-04-29 09:06:11

質問

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

さて、私の疑問は、Visual BasicがC#とどのように違うのかという点で、Visual Basicが stringValue.Length 条件を for ループが発生するたびに文字列の長さが変化するにもかかわらず、 ループの条件として使用します。一方、C#では stringValue.Length の中で for のループ条件では、ループが発生するたびに文字列の初期値が変更されます。これはなぜでしょうか?

どのように解決するのですか?

C#では、ループ境界条件は各反復で評価されます。VB.NETでは、ループに入るときのみ評価されます。

ということは、問題のC#版では、ループ境界条件の長さは stringValue の長さがループ内で変更されているため、最終的なループ変数の値が変更されることになります。

VB.NETでは、最後の条件は包括的なので <= の代わりに < をC#に置き換えます。

C#の終了条件評価には、「変動はしないが計算にコストがかかる」場合でも、ループの前に一度だけ計算するべきだという副次的な意味合いがある。