最好的方式做到这一点是依靠现有的定界数据解析器。 .Split()
方法通常是非常糟糕的:性能低于标准,并且所有边缘情况下的国王(比你想象的要多),它在哪里工作不好。甚至有一个解析器已经内置到.Net中:Microsoft.VisualBasic.FileIO.TextFieldParser。
此外,ArrayLists真的只存在于.Net 2.0兼容性。没有任何理由再使用一个。至少,使用通用的List(Of String)
。在这种情况下,虽然,你最好的选择是建立一个快速的类:
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
现在你读你的文件是这样的:
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
即使类的定义,这是一个整个代码比原始代码少,而且维护起来也容易得多。
我还很想写这为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
我有两个最后的修改建议。第一个将构造函数添加到接受字符串数组的Question类型。这将从代码中移除一点高级语法(对象初始值设定项),并简化通过实际读取数据的代码部分的读取。第二种方法是使ReadQuestions()
方法成为Question
类型的共享成员。最后的结果是这样的:
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
你从你现有的代码中调用这一切都像这样:
Dim Questions = Question.ReadFromFile(My.Resources.ResourceManager.GetObject(globalVariables.currSubject))
For Each q As Question in Questions
'...
Next
为什么仍然使用ArrayList?现在有更好的选择。列表(问题)例如 – Steve 2014-09-23 13:41:10
要用更明显的语句回答您的具体问题,请在第一次运行后sr.peek = -1。你必须达到弦乐的结束或停止。如果我是你,我会尝试一种不同的循环方法。 – Kat 2014-09-23 13:42:19
你会为此更好地创建一个'Quiz'类,而不是在几个数组中存储相关数据 – Plutonix 2014-09-23 13:43:40