VB.NET kodunu C # 'a taşırken bir for döngüsü neden farklı davranıyor?


87

Bir projeyi Visual Basic'ten C #'ye geçirme sürecindeyim ve forkullanılan bir döngünün nasıl bildirildiğini değiştirmek zorunda kaldım .

VB.NET'te fordöngü aşağıda açıklanmıştır:

Dim stringValue As String = "42"

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

Hangi çıktılar:

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 # 'da fordöngü aşağıda bildirilmiştir:

string stringValue = "42";

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

Ve çıktı:

42 1
42 1 2
42 1 2 3

Bu açıkça doğru değil, bu yüzden kodu çok az değiştirmek zorunda kaldım ve dizenin uzunluğunu tutacak bir tamsayı değişkeni dahil ettim.

Lütfen aşağıdaki koda bakın:

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

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

Ve çıktı:

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

Şimdi sorum stringValue.Length, fordöngü her oluştuğunda dizenin uzunluğu değişse de , Visual Basic'in Visual Basic açısından C # 'dan nasıl farklılaştığını çözüyor . C # 'da ise stringValue.Length, fordöngü koşulunu kullanırsam, döngü her gerçekleştiğinde ilk dize değerini değiştirir. Bu neden?


8
Microsoft , sorununun ne olduğunu açıkça özetliyor ...
Codexer

39
@ Çöđěxěŕ: Dur lütfen. Bağlama bakılmaksızın başlıktaki etiketleri robot olarak kaldırmak yardımcı olsaydı, web sitesi bunu yapardı.
Ry-

11
@ Çöđěxěŕ Bununla ilgili bazı bilgilere buradan ulaşabilirsiniz
pushkin

35
@ Çöđěxěŕ İki gönderinin birbiriyle çeliştiğini düşünmüyorum. Önemli olan şudur: "bu şey hakkında soru - etiket" gibi başlığa garip bir şekilde etiket yapıştırmayın. Ancak başlık, etiketi içeren tam bir cümle ise, o zaman bazen sorun olmaz. "Geçiş yaparken neden for döngüsü farklı davranıyor" çok genel bir başlık gibi geliyor.
pushkin

26
@ Çöđěxěŕ "VB.NET kodunu C # 'a geçirmek" açıkça başlığa faydalı bilgiler ekleyen tam bir ifadedir. Netliği azaltan düzenlemeler yapmayın. Umarım, bu fikir, onu yedeklemek için bir Meta gönderisine ihtiyacımız olmayacak kadar sağduyudur.
jpmc26

Yanıtlar:


115

C # 'da, döngü sınır koşulu her yinelemede değerlendirilir. VB.NET'te, yalnızca döngüye girişte değerlendirilir.

Dolayısıyla söz konusu C # versiyonunda stringValuedöngüde uzunluğu değiştiği için son döngü değişkeni değeri değişecektir.

VB.NET'te, son koşul kapsayıcıdır, bu nedenle C # <=yerine kullanırsınız <.

C # 'daki son durum değerlendirmesi, değişmese de hesaplanması pahalı olsa bile, döngüden hemen önce bir kez hesaplanması gerektiği sonucuna sahiptir.


Yanıt için teşekkürler. Şimdi kullanmanın <=yineleme yapmama ve VB koduyla aynı çıktıya sahip olmama izin verdiğini anlıyorum . Bununla birlikte, tamsayı değişkenini neden bildirmek zorunda kaldığımı ve VBbuna gerek olmadığını bilmekle daha çok ilgileniyorum . Aynı çıktıyı gösterecek şekilde sorumu güncelleyeceğim.
slee423

@ slee423 Nedeni cevabımın ilk cümlesinde verilmiştir. Çünkü uzunluğustringValue değiştiğinden, son döngü değişkeni değeri değiştirilecektir.
Andrew Morton

1
özür dilerim, cevap için teşekkürler. Ve benim için daha ayrıntılı olarak açıkladığınız için teşekkürler.
slee423

1
@ slee423 Bunu gerçekten açıklığa kavuşturduğu için cevaba ekledim.
Andrew Morton

22

Şimdi sorum, döngü her oluştuğunda dizenin uzunluğu değişse bile, for döngüsündeki stringValue.Length koşulunu kullanarak VB'nin VB açısından C # 'dan nasıl farklılaştığını çözüyor.

Göre VB.NET belgelerinde:

counterBir döngü içindeyken değerini değiştirirseniz, kodunuzun okunması ve hata ayıklaması daha zor olabilir. Değerinin değiştirilmesi start, endya da stephalka ilk giriş belirlenmiştir yineleme değerleri etkilemez.

Dolayısıyla, değeri bir To 10 - stringValue.Lengthkez değerlendirilir ve döngüler çıkana kadar yeniden kullanılır.

Ancak, ifade için c # 'lara bakın

Eğer for_conditionmevcut veya değerlendirme verimleri halinde değiltrue , kontrol gömülü tablosuna aktarılır. Kontrol, gömülü ifadenin son noktasına ulaştığında (muhtemelen bir continue ifadesinin yürütülmesinden), varsa, ifadeleri for_iteratorsırayla değerlendirilir ve ardından for_conditionadımdaki ifadesinin değerlendirilmesinden başlayarak başka bir yineleme gerçekleştirilir. yukarıda.

Bu, temelde durumun ; i <= 10 - stringValueLength;her seferinde yeniden değerlendirildiği anlamına gelir .

Bu nedenle, gördüğünüz gibi, kodu kopyalamak istiyorsanız, döngüyü başlatmadan önce c # 'da son sayacı bildirmeniz gerekir.


11

Örneği daha anlaşılır kılmak için, her iki for döngüsünü de C # while döngülerine çevireceğim .

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++;
}

Fark şudur:

VB.NET maksimum değeri önbelleğe alır i, ancak C # her seferinde yeniden hesaplar.


2
Döngüleri
zamana

10
Başlangıçta anlamama yardımcı oldu for loops, çok daha anlaşılır olduklarını düşünüyorum. Bu yüzden while loops, anlamaya yardımcı olmak için içindeki örnekleri 'çevirdim' .
Maxime Recuerda

7

Çünkü forVB, forC # dilindekinden (veya başka herhangi bir C benzeri dilden) farklı bir anlambilimseldir.

VB'de forifade, bir sayacı özellikle bir değerden diğerine artırır.

C, C ++, C # vb. forSürümlerde ifade yalnızca üç ifadeyi değerlendirir:

  • İlk ifade geleneksel olarak bir ilklendirmedir
  • İkinci ifade, uç koşulun karşılanıp karşılanmadığını belirlemek için her yinelemenin başlangıcında değerlendirilir.
  • Üçüncü ifade, geleneksel olarak bir artırıcı olan her yinelemenin sonunda değerlendirilir.

VB'de, bir terminal değerine karşı test edilebilecek ve her yinelemede artırılabilecek bir sayısal değişken sağlamalısınız.

C, C ++, C #, vb. De, üç ifade minimum düzeyde sınırlandırılmıştır; koşullu ifade bir doğru / yanlış (veya C, C ++ 'da tamsayı sıfır / sıfır olmayan) olarak değerlendirilmelidir. Hiçbir şekilde bir başlatma gerçekleştirmenize gerek yoktur, herhangi bir değer aralığı üzerinde herhangi bir türü yineleyebilir, karmaşık bir yapı üzerinde bir işaretçiyi veya başvuruyu yineleyebilir veya hiçbir şeyi yinelemeyebilirsiniz.

Bu nedenle, C # vb. De, koşul ifadesi her yinelemede tam olarak değerlendirilmelidir, ancak VB'de yineleyicinin uç değeri başlangıçta değerlendirilmeli ve tekrar değerlendirilmesine gerek yoktur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.