2012-12-11 5 views
0
Imports System.IO 
Imports System 

Public Class Form1 

    Private Class movie 
     Public name As String 
     Public actors() As String 
     Public year As String 
     Public country As String 
     Public votes As String 

    End Class 

    Private movies(0) As movie 
    Private fs As FileStream 
    Private input As StreamReader 

    Private Sub LoadToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LoadToolStripMenuItem.Click 
     OpenFileDialog1.ShowDialog() 
     Dim i As Integer = 0 

     Dim currentmv As New movie 
     Dim reader As String() 


     If File.Exists(OpenFileDialog1.FileName) Then 

      lblPath.Text = OpenFileDialog1.FileName 
      Dim iFile As New StreamReader(lblPath.Text) 

      While Not iFile.EndOfStream 

       reader = iFile.ReadLine.Split(";") 

       currentmv.name = reader(0) 
       currentmv.actors = reader(1).Split(",") 
       currentmv.year = reader(2) 
       currentmv.country = reader(3) 
       currentmv.votes = reader(4) 

       lbMovies.Items.Add(currentmv.name) 

       movies(i) = currentmv 

       i = i + 1 
       ReDim movies(i) 

      End While 
     End If 

    End Sub 

    Private Sub lbMovies_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lbMovies.SelectedIndexChanged 
     Dim i As Integer 

     For i = 0 To movies(lbMovies.SelectedIndex).actors.Length 

      lbActors.Items.Add(movies(lbMovies.SelectedIndex).actors(i)) 

     Next 

    End Sub 
End Class 

길이를 요청할 때 문제가 발생합니다. 그것은 그것은 null 참조라고하지만, 이것에 어떤 실수를 볼 수 없습니다. 객체 배열에서 배열의 길이를 요청할 때 문제가 있습니까?미스터리 null 참조

+0

당신이 예외가 어디에 실제로 지점에서로드 된 파일을 했습니까? 디버깅을 시도 할 때 어떤 일이 발생 했습니까? –

답변

3

Preserve없이 Nothing 모든 요소를 ​​초기화합니다

ReDim Preserve movies(i) 

IIRC ReDim을보십시오.

+0

ReDim은 편리하지만 낭비 적이기 때문에 Preserve (http://www.aspheute.com/english/20001025.asp 참조)를 사용해도 항상 새로운 Array를 만듭니다. igrimpe가 말했듯이 List (Of ...)를 사용하면 항목 목록이 여러 번 성장하거나 줄어들 때 선호되는 방법입니다. ReDim은 달리 실행하지 않으면 괜찮습니다 (여러 번 재사용되는 버퍼를 만드는 경우와 같이). 배열 크기가 작 으면 (100 개 요소 미만) Preserve로 유지하십시오. – rskar

1

배열을 사용하여 데이터를 저장하고 "이름"을 목록 상자에 저장하는 작업은 필요하지 않습니다. 목록 상자는 String이 아니라 Object을 저장합니다. 목록 상자 자체에 데이터를 저장할 수 있습니다.

Private Class Data 
    Public SomeNumber As Integer 
    Public SomeString As String 
    Public Overrides Function ToString() As String 
     Return String.Format("{0} ({1})", SomeString, SomeNumber) 
    End Function 
End Class 

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 

    ListBox1.Items.Add(New Data With {.SomeString = "John", .SomeNumber = 12}) 
    ListBox1.Items.Add(New Data With {.SomeString = "Paul", .SomeNumber = 36}) 
    ListBox1.Items.Add(New Data With {.SomeString = "Ringo", .SomeNumber = 48}) 

End Sub 

Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged 
    Dim d As Data = DirectCast(sender, ListBox).SelectedItem 
    If d IsNot Nothing Then 
     Console.WriteLine(d.ToString) 
    End If 
End Sub 

또는 당신은 목록에서 데이터를 저장하고 bind 그것은 당신의 목록 상자에 :

Private Class Data 
    Public SomeNumber As Integer 
    Public SomeString As String 
    Public Overrides Function ToString() As String 
     Return String.Format("{0} ({1})", SomeString, SomeNumber) 
    End Function 
End Class 

Private datalist As New List(Of Data) 

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 

    datalist.Add(New Data With {.SomeString = "John", .SomeNumber = 12}) 
    datalist.Add(New Data With {.SomeString = "Paul", .SomeNumber = 36}) 
    datalist.Add(New Data With {.SomeString = "Ringo", .SomeNumber = 48}) 

    ListBox1.DataSource = datalist 

End Sub 

Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged 
    Dim d As Data = DirectCast(sender, ListBox).SelectedItem 
    If d IsNot Nothing Then 
     Console.WriteLine(d.ToString) 
    End If 
End Sub 
+0

List (Of ...)가 실제로 내가 사용하는 것, ReDim Preserve를 넘기는 더 좋은 방법이기 때문에 +1. – rskar