2012-11-06 5 views
2

Если я положу точку останова в строке currentrow = MyParser.ReadFields() , currentrow по-прежнему будет содержать значения предыдущей строки, проанализированные из файла. После выполнения currentrow = MyParser.ReadFields() текущие значения строки файла сохраняются.Почему значения в массиве сохраняются в цикле while? (VB.NET)

Поскольку currentrow объявлен внутри цикла While, не должно ли предыдущее значение текущего значения покидать область видимости при повторном входе в цикл While? Почему currentrow все еще сохраняет значения из последней строки в файле?

Нужно ли мне менять Dim currentrow As String() на Dim currentRow() = New String() {}? Зачем?

If File.Exists(filename) Then 
     Using MyParser As New FileIO.TextFieldParser(filename) 
      MyParser.TextFieldType = FileIO.FieldType.Delimited 
      MyParser.SetDelimiters("~") 
      While Not MyParser.EndOfData 
       Try 
        Dim currentrow As String() 
        'at this point, currentrow still contains prev values 
        currentrow = MyParser.ReadFields() 
       Catch 
       End Try 
      End While 
     End Using 
End If 
+0

Это плохое использование File.Exists(). Просто откройте файл и обработайте FileNotFoundException. –

+0

Кроме того, обязательно плохо, что currentrow все еще имеет старые значения, если вы правильно структурируете цикл? –

+0

@JoelCoehoorn: Можете ли вы дать мне дополнительную информацию о различии между улавливанием исключения или проверкой с File.Exists() и почему последнее не так хорошо? – user1620141

ответ

2

Потому что вы только объявили переменную цикла, в отличие от этого, что приводит к правильному значению Nothing на каждой итерации:

Dim currentrow As String() = Nothing 

или даже лучше

Dim currentrow As String() = MyParser.ReadFields() 

«Dim «сам по себе без явной инициализации будет оптимизирован как избыточный.

Даже если вы назначили Nothing, он будет всегда сбрасываться до Nothing на каждой итерации. Если вы только объявляете переменную, она всегда будет содержать «неправильное» старое значение, даже если вы затем будете использовать Console.Write или MessageBox.Show.

Поэтому всегда указывайте значение по умолчанию в переменной цикла, чтобы избежать побочных эффектов.

Sidenote C# позволяет избежать этого источника ошибок с compiler warning CS0165: Использованием неназначенного локального переменной 'VARIABLENAME'.

Итак, если вы попытаетесь использовать эту непризнанную переменную до того, как она будет назначена, вы даже не сможете скомпилировать ее с C#. Я не знаю, почему это разрешает VB.NET.

+0

Спасибо за ваш ответ. Итак, текущее время не воссоздается на каждой итерации цикла? Чтобы уточнить, в первый раз, когда мы входим в цикл, объявляется currentrow. Почему же тогда он не получает переоформление каждой итерации цикла после этого? – user1620141

+2

@ user1620141: Я хотел бы показать вам спецификацию языка или блог, но, к сожалению, я ничего не нахожу. 'currentrow' будет переназначаться в' currentrow = MyParser.ReadFields() ', а не в строке объявления, так как это будет« оптимизировано »/ опущено, поскольку оно избыточно в цикле. Но это может быть источником ошибок. –

1

Помните, что все переменные в VB имеют область действия блока, в которой они объявлены, но время жизни всей подпрограммы (*) (эффективно от того, где они объявлены до конца подпрограммы) re всегда инициализируется до Nothing, что бы это ни значило для фактического типа.

Dim outer As Integer 
For i = 1 To 2 
Dim inner As Integer 
Try 
    Dim inner2 As Integer 
    Do 
    Dim inner3 As Integer 
    While True 
    Dim inner4 As Integer 
    Console.WriteLine(outer & ", " & inner & ", " & inner2 & ", " & inner3 & ", " & inner4) 
    outer = i 
    inner = i 
    inner2 = i 
    inner3 = i 
    inner4 = i 
    Exit While 
    End While 
    Loop Until True 
Catch 
End Try 
Next 

Приведенные выше результаты:

0, 0, 0, 0, 0 
1, 1, 1, 1, 1 

(*), скрытых процедуры/закрытия влияют на это. См. Мой separate question.

+0

Спасибо за пример и ссылку на ваш вопрос. Из любопытства, знаете ли вы, является ли это поведение эксклюзивным для VB.NET, или будет ли вывод на C# одинаковым? – user1620141

+0

C# не позволяет вам получать доступ к переменным до их назначения. –

Смежные вопросы