The best way to do this is to rely on an existing delimited data parser. The .Split() method is very often horrible for this: performance is sub-par, and there are all kings of edge cases (more than you'd think) where it just doesn't work well. There is even a parser already built into .Net: Microsoft.VisualBasic.FileIO.TextFieldParser.
Additionally, ArrayLists really only exist for pre-.Net 2.0 compatibility. There's is no good reason to ever use one any more. At very least, use a generic List(Of String). In this case, though, your best option is to build a quick class:
Public Class Question
Public Property QuestionText As String
Public Property OptionA As String
Public Property OptionB As String
Public Property OptionC As String
Public Property OptionD As String
Public Property Answer As String
End Class
Now you read your file like this:
Dim results As New List(Of Question)()
Using rdr As New TextFieldParser(My.Resources.ResourceManager.GetObject(globalVariables.currSubject))
rdr.Delimiters = new String() {"##"}
Dim row() As String
While Not rdr.EndOfData
row = rdr.ReadFields()
results.Add(New Question() {
QuestionText = row(0),
OptionA = row(1),
OptionB = row(2),
OptionC = row(3),
OptionD = row(4),
Answer = row(5)
})
End While
End Using
Even with the class definition, that's a whole let less code than the original, and it's much easier to maintain, as well.
I'd also be tempted to write this as an Iterator:
Public Iterator Function ReadQuestions(ByVal FileName As String) As IEnumerable(Of Question)
Using rdr As New TextFieldParser(FileName)
rdr.Delimiters = new String() {"##"}
Dim row() As String
While Not rdr.EndOfData
row = rdr.ReadFields()
Yield New Question() {
QuestionText = row(0),
OptionA = row(1),
OptionB = row(2),
OptionC = row(3),
OptionD = row(4),
Answer = row(5)
}
End While
End Using
End Function
I have two final changes to suggest. The first to add a constructor to the Question type that accepts a string array. This would remove one bit of advanced syntax (the object initializer) from the code, and simplify reading through the portion of the code that actually reads the data. The second isto make the ReadQuestions() method a shared member of the Question type. The final result is this:
Public Class Question
Public Property QuestionText As String
Public Property OptionA As String
Public Property OptionB As String
Public Property OptionC As String
Public Property OptionD As String
Public Property Answer As String
Public Sub New(ByVal data() As String)
'Add error handling here
QuestionText = data(0),
OptionA = data(1),
OptionB = data(2),
OptionC = data(3),
OptionD = data(4),
Answer = data(5)
End Sub
Public Shared Iterator Function ReadFromFile(ByVal FileName As String) As IEnumerable(Of Question)
Using rdr As New TextFieldParser(FileName)
rdr.Delimiters = new String() {"##"}
While Not rdr.EndOfData
Yield New Question(rdr.ReadFields())
End While
End Using
End Function
End Class
And you call all this from your existing code like so:
Dim Questions = Question.ReadFromFile(My.Resources.ResourceManager.GetObject(globalVariables.currSubject))
For Each q As Question in Questions
'...
Next
Quizclass for that rather than storing related data in several arrays