Почему цикл for ведет себя по-разному при переносе кода VB.NET в C #? - PullRequest
0 голосов
/ 02 октября 2018

Я в процессе переноса проекта из 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, он меняет начальное значение строки каждый раз, когда происходит цикл.Почему это?

Ответы [ 4 ]

0 голосов
/ 03 октября 2018

Поскольку for в VB отличается от семантики for в C # (или любом другом C-подобном языке)

В VB оператор for специально увеличивает счетчик содно значение другому.

В C, C ++, C # и т. д. оператор for просто вычисляет три выражения:

  • Первое выражение обычно является инициализацией
  • Второе выражение оценивается в начале каждой итерации, чтобы определить, было ли выполнено условие терминала
  • Третье выражение вычисляется в конце каждой итерации, что обычно является инкрементатором.

В VB вы должны предоставить числовую переменную, которая может быть проверена по значению терминала и увеличена на каждой итерации

В C, C ++, C # и т. Д.,три выражения минимально ограничены;условное выражение должно иметь значение true / false (или целое ноль / ненулевое значение в C, C ++).Вам вообще не нужно выполнять инициализацию, вы можете выполнять итерации любого типа по любому диапазону значений, итерировать указатель или ссылку на сложную структуру или вообще ничего не повторять.

Итак, в C #и т. д. выражение условия должно быть полностью оценено на каждой итерации, но в VB конечное значение итератора должно оцениваться в начале, и его не нужно оценивать снова.

0 голосов
/ 02 октября 2018

Теперь мой вопрос решается вокруг того, как VB отличается от C # в терминах VB, используя условие stringValue.Length в цикле for, даже если каждый раз, когда происходит цикл, длина строки изменяется.

Согласно документации VB.NET :

Если вы измените значение counter в цикле, ваш код может быть более трудным для чтения и отладки.,Изменение значения start, end или step не влияет на значения итерации, которые были определены при первом вводе цикла.

Итак, значение To 10 - stringValue.Lengthоценивается один раз и используется повторно до выхода из циклов.

Однако посмотрите на c # для утверждения

Если for_condition отсутствует или если оценкадает true, управление передается во встроенный оператор.Когда и если управление достигает конечной точки встроенного оператора (возможно, из-за выполнения оператора continue), выражения for_iterator, если они есть, вычисляются последовательно, а затем выполняется другая итерация, начиная с оценкиfor_condition на шаге выше.

Это означает, что условие ; i <= 10 - stringValueLength; вычисляется снова каждый раз.

Итак, как вы видели, если вы хотите повторитькод, вам нужно объявить окончательный счетчик в C # перед началом цикла.

0 голосов
/ 02 октября 2018

Чтобы сделать пример более понятным, я преобразую оба для циклов в C # , в то время как циклы .

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 # пересчитывает его каждый раз.

0 голосов
/ 02 октября 2018

В C # граничное условие цикла оценивается на каждой итерации.В VB.NET он оценивается только при входе в цикл.

Итак, в версии C # в вопросе, потому что длина stringValue изменяется в цикле, окончательное значение переменной циклабудет изменено.

В VB.NET конечное условие является включающим, поэтому вы должны использовать <= вместо < в C #.

Оценка конечного условия в C # имеет следствие, что даже еслионо не меняется, но его стоит вычислить, тогда его следует вычислять только один раз перед циклом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...