Jestem w trakcie migracji projektu z Visual Basic do C # i musiałem zmienić sposób for
deklarowania używanej pętli.
W VB.NET for
pętla jest zadeklarowana poniżej:
Dim stringValue As String = "42"
For i As Integer = 1 To 10 - stringValue.Length
stringValue = stringValue & " " & CStr(i)
Console.WriteLine(stringValue)
Next
Które wyjścia:
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
W C # for
pętla jest zadeklarowana poniżej:
string stringValue = "42";
for (int i = 1; i <= 10 - stringValue.Length; i ++)
{
stringValue = stringValue + " " + i.ToString();
Console.WriteLine(stringValue);
}
A wynik:
42 1
42 1 2
42 1 2 3
To oczywiście nie jest poprawne, więc musiałem nieznacznie zmienić kod i dołączyć zmienną całkowitą, która utrzymywałaby długość ciągu.
Zobacz poniższy kod:
string stringValue = "42";
int stringValueLength = stringValue.Length;
for (int i = 1; i <= 10 - stringValueLength; i ++)
{
stringValue = stringValue + " " + i.ToString();
Console.WriteLine(stringValue);
}
A wynik:
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
Teraz moje pytanie dotyczy tego, jak Visual Basic różni się od C # pod względem Visual Basic przy użyciu stringValue.Length
warunku w for
pętli, mimo że za każdym razem, gdy występuje pętla, zmienia się długość ciągu. Natomiast w C #, jeśli używam warunku stringValue.Length
w for
pętli, zmienia on początkową wartość ciągu za każdym razem, gdy występuje pętla. Dlaczego to?
Odpowiedzi:
W języku C # warunek brzegowy pętli jest oceniany przy każdej iteracji. W VB.NET jest oceniany tylko przy wejściu do pętli.
Tak więc w wersji C # w pytaniu, ponieważ długość
stringValue
jest zmieniana w pętli, ostateczna wartość zmiennej pętli zostanie zmieniona.W VB.NET ostateczny warunek jest włącznie, więc
<=
zamiast<
w C # należy go używać .Ocena warunku końcowego w C # ma taki wniosek, że nawet jeśli nie zmienia się, ale jest kosztowna do obliczenia, to powinna zostać obliczona tylko raz przed pętlą.
źródło
<=
pozwala mi na iterację i daje takie same wyniki, jak kod VB. Jednak bardziej interesuje mnie, dlaczego musiałem zadeklarować zmienną całkowitą, aVB
nie musiałem tego robić. Zamierzam zaktualizować moje pytanie, aby wyświetlało ten sam wynik.stringValue
w pętli zmienia się długość , ostateczna wartość zmiennej pętli zostanie zmieniona.Zgodnie z dokumentacją VB.NET :
Tak więc wartość
To 10 - stringValue.Length
jest obliczana raz i ponownie używana do zakończenia pętli.Jednak spójrz na C # dla instrukcji
Co w zasadzie oznacza, że warunek
; i <= 10 - stringValueLength;
jest oceniany ponownie za każdym razem.Tak więc, jak widziałeś, jeśli chcesz zreplikować kod, musisz zadeklarować końcowy licznik w języku c # przed uruchomieniem pętli.
źródło
Aby uczynić przykład bardziej zrozumiałym, przekonwertuję obie pętle for na pętle while w języku 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++; }
DO#
string stringValue = "42"; int i = 1; while (i <= 10 - stringValue.Length) { stringValue = stringValue + " " + stringValue.Length.ToString(); Console.WriteLine(stringValue); i++; }
Różnica jest zatem taka:
źródło
for loops
na początku, myślę, że są one dużo bardziej zrozumiałe. Dlatego „przetłumaczyłem” przykłady w językuwhile loops
, aby ułatwić zrozumienie.Ponieważ
for
in VB jest inną semantyczną niżfor
in C # (lub jakikolwiek inny język podobny do C)W języku VB
for
instrukcja zwiększa wartość licznika z jednej wartości do drugiej.W językach C, C ++, C # itp.
for
Instrukcja po prostu ocenia trzy wyrażenia:W VB musisz podać zmienną numeryczną, którą można przetestować względem wartości końcowej i zwiększać przy każdej iteracji
W językach C, C ++, C # itd. Te trzy wyrażenia są ograniczone w minimalnym stopniu; wyrażenie warunkowe musi mieć wartość prawda / fałsz (lub liczbę całkowitą zero / niezerową w C, C ++). Nie musisz w ogóle wykonywać inicjalizacji, możesz iterować dowolny typ w dowolnym zakresie wartości, iterować wskaźnik lub odwołanie po złożonej strukturze lub w ogóle nie wykonywać iteracji.
Tak więc w C # itd. Wyrażenie warunku musi być w pełni ocenione w każdej iteracji, ale w VB wartość końcowa iteratora musi zostać oszacowana na początku i nie musi być oceniana ponownie.
źródło