-1

配列を初期化して値を割り当てようとしていますが、問題があります

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
4

3 に答える 3

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
于 2014-11-30T15:29:00.970 に答える
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

サイズが変更された場合、ループを制御するために構造体配列の境界が使用されることに注意してください。つまり、配列のサイズを 1 つの場所 (構造体) で変更するだけで済みます。

また、case ステートメントで値が割り当てられることにも注意してください。これにより、配列の次元が変更された場合の実行時エラーが防止されます。適切な値を設定していない場合、論理エラーが発生する可能性がありますが、これらは適切な単体テストでキャッチできます。

追加情報

私の最初の回答には、For Eachを反復するステートメントが含まれていましたmyvalues。ただし、明らかに、これは構造体の配列に対して有効な操作ではありFor Eachません。変数で取得した要素は、実際には配列で更新されません。参照元が違うようです。

外部 DLL の呼び出しに使用しない限り、VB.Net の構造体を扱ったことがないので、この動作には驚かされました。絶対に構造体を使用しなければならない場合を除き、実装を に変更することを強くお勧めし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
于 2012-07-21T18:50:39.767 に答える
0

これを行うには1つのトリックがあります

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
于 2013-11-28T06:51:45.547 に答える