Tại sao vòng lặp for lại hoạt động khác khi di chuyển mã VB.NET sang C #?


87

Tôi đang trong quá trình di chuyển một dự án từ Visual Basic sang C # và tôi đã phải thay đổi cách forkhai báo một vòng lặp đang được sử dụng.

Trong VB.NET, forvòng lặp được khai báo dưới đây:

Dim stringValue As String = "42"

For i As Integer = 1 To 10 - stringValue.Length
   stringValue = stringValue & " " & CStr(i)
   Console.WriteLine(stringValue)
Next

Đầu ra nào:

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

Trong C #, forvòng lặp được khai báo dưới đây:

string stringValue = "42";

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

Và đầu ra:

42 1
42 1 2
42 1 2 3

Điều này rõ ràng là không chính xác vì vậy tôi đã phải thay đổi mã một chút và bao gồm một biến số nguyên sẽ giữ độ dài của chuỗi.

Vui lòng xem mã bên dưới:

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

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

Và đầu ra:

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

Bây giờ câu hỏi của tôi giải quyết xung quanh việc Visual Basic khác với C # như thế nào về Visual Basic bằng cách sử dụng stringValue.Lengthđiều kiện trong forvòng lặp mặc dù mỗi lần vòng lặp xảy ra, độ dài của chuỗi thay đổi. Trong khi đó trong C # nếu tôi sử dụng điều kiện stringValue.Lengthtrong forvòng lặp, nó sẽ thay đổi giá trị chuỗi ban đầu mỗi khi vòng lặp xảy ra. Tại sao thế này?


7
Microsoft vạch ra rõ ràng vấn đề của bạn là gì ...
Çöđěxěŕ

39
@ Çöđěxěŕ: Làm ơn dừng lại. Nếu việc loại bỏ các thẻ từ tiêu đề một cách tự động mà không liên quan đến ngữ cảnh là hữu ích, thì trang web sẽ làm điều đó.
Ry-

11
@ Çöđěxěŕ Bạn có thể tìm thấy một số thông tin về điều đó tại đây
pushkin

35
@ Çöđěxěŕ Tôi không nghĩ rằng hai bài viết mâu thuẫn với nhau. Vấn đề là: đừng vụng về dán một thẻ vào tiêu đề như "câu hỏi về điều này - thẻ". Nhưng nếu tiêu đề là một câu hoàn chỉnh bao gồm thẻ, thì đôi khi nó vẫn ổn. "Tại sao vòng lặp for lại hoạt động khác khi di chuyển" giống như một cách tiêu đề quá chung chung.
pushkin

26
@ Çöđěxěŕ "chuyển mã VB.NET sang C #" rõ ràng là một cụm từ đầy đủ bổ sung thông tin hữu ích cho tiêu đề. Đừng thực hiện các chỉnh sửa làm giảm độ rõ ràng. Hy vọng rằng khái niệm đó đủ thông thường để chúng ta không cần một bài đăng Meta để sao lưu nó.
jpmc26

Câu trả lời:


115

Trong C #, điều kiện biên của vòng lặp được đánh giá trên mỗi lần lặp. Trong VB.NET, nó chỉ được đánh giá khi vào vòng lặp.

Vì vậy, trong phiên bản C # trong câu hỏi, vì độ dài của stringValueđang được thay đổi trong vòng lặp, giá trị biến vòng lặp cuối cùng sẽ bị thay đổi.

Trong VB.NET, điều kiện cuối cùng là bao gồm, vì vậy bạn sẽ sử dụng <=thay vì <trong C #.

Đánh giá điều kiện cuối trong C # có hệ quả là ngay cả khi nó không thay đổi nhưng tính toán rất tốn kém, thì nó chỉ nên được tính một lần trước vòng lặp.


Cảm ơn vi đa trả lơi. Bây giờ tôi nhận ra rằng việc sử dụng <=cho phép tôi lặp lại và có kết quả đầu ra giống như mã VB. Tuy nhiên, tôi quan tâm hơn đến việc biết tại sao tôi phải khai báo biến số nguyên và VBtôi không phải khai báo. Tôi sẽ cập nhật câu hỏi của mình để hiển thị cùng một kết quả.
sle423

@ sle423 Lý do được đưa ra trong câu đầu tiên của câu trả lời của tôi. Bởi vì độ dài của stringValueđang được thay đổi trong vòng lặp, giá trị biến cuối cùng của vòng lặp sẽ bị thay đổi.
Andrew Morton

1
xin lỗi, cảm ơn vì câu trả lời đó. Và cảm ơn vì đã giải thích chi tiết hơn cho tôi.
sle423

1
@ sle423 Tôi đã thêm điều đó vào câu trả lời vì nó thực sự làm rõ nó.
Andrew Morton

22

Bây giờ câu hỏi của tôi giải quyết xung quanh việc VB khác với C # như thế nào về VB bằng cách sử dụng điều kiện stringValue.Length trong vòng lặp for mặc dù mỗi lần vòng lặp xảy ra, độ dài của chuỗi thay đổi.

Theo tài liệu VB.NET :

Nếu bạn thay đổi giá trị của counterwhile bên trong một vòng lặp, mã của bạn có thể khó đọc và gỡ lỗi hơn. Thay đổi giá trị của start, endhoặc stepkhông ảnh hưởng đến giá trị lặp được xác định khi vòng lặp lần đầu tiên được nhập vào.

Vì vậy, giá trị của To 10 - stringValue.Lengthđược đánh giá một lần và được sử dụng lại cho đến khi các vòng lặp thoát ra.

Tuy nhiên, hãy nhìn vào câu lệnh c #

Nếu for_conditionkhông có hoặc nếu kết quả đánh giá true, quyền kiểm soát được chuyển sang câu lệnh nhúng. Khi nào và nếu điều khiển đạt đến điểm kết thúc của câu lệnh nhúng (có thể từ việc thực hiện câu lệnh continue), các biểu thức của for_iterator, nếu có, được đánh giá theo trình tự và sau đó một lần lặp khác được thực hiện, bắt đầu với việc đánh giá for_conditiontrong bước ở trên.

Về cơ bản có nghĩa là điều kiện ; i <= 10 - stringValueLength;được đánh giá lại mỗi lần.

Vì vậy, như bạn đã thấy, nếu bạn muốn sao chép mã, bạn cần khai báo bộ đếm cuối cùng trong c # trước khi bắt đầu vòng lặp.


11

Để làm ví dụ dễ hiểu hơn, tôi sẽ chuyển đổi tất cả cho vòng vào C # vòng lặp 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++;
}

Sự khác biệt sau đó là:

VB.NET lưu trữ giá trị lớn nhất cho i, nhưng C # luôn tính toán lại giá trị đó.


2
Bạn không cần phải vòng chuyển đổi để khi
Panagiotis Kanavos

10
Nó đã giúp tôi hiểu for loopstừ đầu, tôi nghĩ chúng dễ hiểu hơn nhiều. Đây là lý do tại sao tôi 'dịch' các ví dụ trong while loops, để giúp hiểu rõ hơn.
Maxime Recuerda

7

Bởi vì fortrong VB là một ngữ nghĩa khác với fortrong C # (hoặc bất kỳ ngôn ngữ giống C nào khác)

Trong VB, forcâu lệnh cụ thể là tăng một bộ đếm từ giá trị này sang giá trị khác.

Trong C, C ++, C #, v.v., forcâu lệnh chỉ đơn giản đánh giá ba biểu thức:

  • Biểu thức đầu tiên thường là một khởi tạo
  • Biểu thức thứ hai được đánh giá khi bắt đầu mỗi lần lặp để xác định xem điều kiện đầu cuối đã được đáp ứng chưa
  • Biểu thức thứ ba được đánh giá ở cuối mỗi lần lặp, biểu thức này thường là một bộ tăng.

Trong VB, bạn phải cung cấp một biến số có thể được kiểm tra dựa trên giá trị đầu cuối và tăng dần trên mỗi lần lặp

Trong C, C ++, C #, v.v., ba biểu thức bị hạn chế tối thiểu; biểu thức điều kiện phải đánh giá thành true / false (hoặc số nguyên 0 / khác 0 trong C, C ++). Bạn hoàn toàn không cần thực hiện khởi tạo, bạn có thể lặp lại bất kỳ kiểu nào trên bất kỳ phạm vi giá trị nào, lặp lại một con trỏ hoặc tham chiếu qua một cấu trúc phức tạp hoặc không lặp lại bất kỳ thứ gì.

Vì vậy, trong C #, v.v., biểu thức điều kiện phải được đánh giá đầy đủ trên mỗi lần lặp, nhưng trong VB, giá trị đầu cuối của trình lặp phải được đánh giá ngay từ đầu và không cần đánh giá lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.