如何初始化结构中的数组

时间:2012-07-21 18:33:10

标签: vb.net arrays initialization

我正在尝试初始化数组并分配值,但我遇到了问题

Public Structure test1
    <VBFixedArray(6)> Dim Id() As String
    Public Sub initialize()
        ReDim Id(6)
    End Sub
End Structure

Dim myvalues() as test1
...
ReDim myvalues(10)

我试图通过以下

来实现这一目标
For i as short = 0 to 10
    myvalues(i).Id(1) = "V"
    myvalues(i).Id(2) = "H"
    ...
    myvalues(i).Id(6) = "J"
next i

这不起作用,我不确定正确实施?

编辑:

Imports Microsoft.VisualBasic
Module Module1
Structure test1
    <VBFixedArray(6)> Dim Id() As String
    Public Sub initialize()
        ReDim Id(6)
        For im As Integer = 0 To 6
            Id(im) = ""
        Next im
    End Sub
End Structure
Sub Main()
    Dim i As Integer
    Dim myvalues() As test1
    ReDim myvalues(10)
    For Each oTest As test1 In myvalues
        ' Initialize the structure 
        ReDim myvalues(10)
        oTest.initialize()
        ' Now loop through the array based on the bounds it was configured for
        'initialize to empty string(NOT ABLE TO ASSIGN TO> myvalues(i).Id(j))
        'I Get ERROR>>>Object reference not set to an instance of an object<<<<<
        'For i = 0 To 10
        For j As Integer = oTest.Id.GetLowerBound(0) To oTest.Id.GetUpperBound(0)
            ' Set the values in a case statement so that alterations to the size of the index won't break your code.
            Select Case j
                Case 0
                    oTest.Id(j) = "A"
                    myvalues(i).Id(j) = "A"
                Case 1
                    oTest.Id(j) = "B"
                    'myvalues(i).Id(j) = "B"
                Case 2
                    oTest.Id(j) = "C"
                    'myvalues(i).Id(j) = "C"
                Case 3
                    oTest.Id(j) = "D"
                    'myvalues(i).Id(j) = "D"
                Case 4
                    oTest.Id(j) = "E"
                    'myvalues(i).Id(j) = "E"
                Case 5
                    oTest.Id(j) = "F"
                    'myvalues(i).Id(j) = "F"
                Case 6
                    oTest.Id(j) = "G"
                    'myvalues(i).Id(j) = "G"
            End Select
        Next j
        'Next i
    Next 'oTest
        'assign<<<<<<<<<<<<<<<<<<< NOT WORKING>>>>
        '<<Id() is not set to <empty string> it is "Nothing"  I GET ERROR (91) next line and after
        'What am I doing wrong?
        For i = 0 To 10
        Console.WriteLine(myvalues(i).Id(0), myvalues(i).Id(1), myvalues(i).Id(2), myvalues(i).Id(3), myvalues(i).Id(4), myvalues(i).Id(5), myvalues(i).Id(6))
    Next i
End Sub
End Module

3 个答案:

答案 0 :(得分:0)

主要问题是您没有在结构上调用初始化。您应该将循环更改为:

    Dim myvalues() As test1
    ReDim myvalues(10)

    For nI As Integer = myvalues.GetLowerBound(0) To myvalues.GetUpperBound(0)
        With myvalues(nI)
            .initialize()
            For j As Integer = .Id.GetLowerBound(0) To .Id.GetUpperBound(0)
                ' Set the values in a case statement so that alterations to the size of the index won't break your code.
                Select Case j
                    Case 0
                        .Id(j) = "A"
                    Case 1
                        .Id(j) = "B"
                    Case 2
                        .Id(j) = "C"
                    Case 3
                        .Id(j) = "D"
                    Case 4
                        .Id(j) = "E"
                    Case 5
                        .Id(j) = "F"
                    Case 6
                        .Id(j) = "G"
                End Select
            Next
        End With
    Next

    For nI As Integer = myvalues.GetLowerBound(0) To myvalues.GetUpperBound(0)
        With myvalues(nI)
            Console.WriteLine(String.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}", .Id(0), .Id(1), .Id(2), .Id(3), .Id(4), .Id(5), .Id(6)))
        End With
    Next

请注意,在大小更改的情况下,结构数组的边界用于控制循环。这意味着您只需要在一个位置(结构)中更改数组的大小。

另请注意,值在case语句中指定。如果阵列尺寸发生变化,这可以防止运行时错如果您没有设置正确的值,则可能会出现逻辑错误,但这些可以通过良好的单元测试来捕获。

其他信息

我的初始答案包含For Each语句,该语句迭代myvalues。但是,显然,这不是针对结构数组的有效操作:您在For Each变量中获得的元素实际上并未在数组中更新。它似乎是一个不同的参考。

我从未使用VB.Net中的结构,除非我使用它们来调用外部DLL,所以这种行为让我感到惊讶。除非您绝对必须使用结构,否则我强烈建议将实现更改为Class

以下是使用Class的实现:

Public Class test1
    Public Id() As String

    ' Note that we can perform the initialization in the constructor instead of having to call a separate method
    Public Sub New()
        ReDim Id(6)
    End Sub
End Class

    Dim myvalues(10) As test1

    For nI As Integer = myvalues.GetLowerBound(0) To myvalues.GetUpperBound(0)
        ' Create a new instance of the class and assign it to the array element
        myvalues(nI) = New test1
        With myvalues(nI)
            For j As Integer = .Id.GetLowerBound(0) To .Id.GetUpperBound(0)
                ' Set the values in a case statement so that alterations to the size of the index won't break your code.
                Select Case j
                    Case 0
                        .Id(j) = "A"
                    Case 1
                        .Id(j) = "B"
                    Case 2
                        .Id(j) = "C"
                    Case 3
                        .Id(j) = "D"
                    Case 4
                        .Id(j) = "E"
                    Case 5
                        .Id(j) = "F"
                    Case 6
                        .Id(j) = "G"
                End Select
            Next
        End With
    Next

    ' Now we can use a for each
    For Each oTest As test1 In myvalues
        With oTest
            Console.WriteLine(String.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}", .Id(0), .Id(1), .Id(2), .Id(3), .Id(4), .Id(5), .Id(6)))
        End With
    Next

答案 1 :(得分:0)

有一个技巧可以做到这一点

Public Structure Test1
    Private m_ID() As String

    Public Property ID(Index As Integer) As String
        Get
            If m_ID Is Nothing Then initArray()
            Return m_ID(Index)
        End Get
        Set(value As String)
            If m_ID Is Nothing Then initArray()
            m_ID(Index) = value
        End Set
    End Property

    Private Sub initArray()
        ReDim m_ID(6)
    End Sub
End Structure

Dim MyValues() As Test1
ReDim MyValues(10)
For i As Short = 0 To 10
    MyValues(i).ID(1) = "V"
    MyValues(i).ID(2) = "H"
    ....
    MyValues(i).ID(6) = "J"
Next i

答案 2 :(得分:0)

我认为这是你想要的,虽然从帖子中不是很清楚:

Option Infer On
Module Module1

    Structure test1
        Implements ICloneable

        Dim Id As String()
        Public Sub New(ByVal list As String())
            Id = New String(list.Length - 1) {}
            For im As Integer = 0 To Id.Length - 1
                Id(im) = list(im)
            Next im
        End Sub

        Public Sub New(ByVal other As test1)
            Me.New(other.Id)
        End Sub
        Public Function Clone() As Object Implements System.ICloneable.Clone
            Return New test1(Me)
        End Function
    End Structure

    Sub Main()
        Dim i As Integer, N As Integer = 10
        Dim myvalues = New test1(N) {}

        Dim ids = New String() {"A", "B", "C", "D", "E", "F", "G"}
        Dim prototype = New test1(ids)

        For index As Integer = 0 To N
            myvalues(index) = New test1(prototype)
        Next

        For i = 0 To N
            Console.WriteLine(myvalues(i).Id(0), myvalues(i).Id(1), myvalues(i).Id(2), myvalues(i).Id(3), myvalues(i).Id(4), myvalues(i).Id(5), myvalues(i).Id(6))
        Next i
    End Sub

End Module