Обычно я использую C# и пытаюсь преобразовать программиста на qbasic в радость объектно-ориентированного программирования, облегчив его работу с VB 2005.
Ниже представлена чрезвычайно упрощенная версия того, что я пытаюсь достичь. Он успешно компилируется, но для всех элементов в массиве объектов карты установлено значение «Ничего». Тестовая строка выдает исключение NullReferenceException. Что я делаю неправильно?
Sub Main()
Dim deck1 As New Deck
Console.WriteLine("Test: " & deck1.cards(2).face)
End Sub
Class Card
Public face As String
Sub New()
face = "Blank"
End Sub
End Class
Class Deck
Public cards(51) As Card
End Class
В качестве альтернативы, плохая работа для VB за то, что он сделал это таким непонятным;) (Но да, я бы не заметил этого ...)





Да, когда вы создаете массив в .NET, каждому элементу массива присваивается значение по умолчанию для типа элемента - null / Nothing для классов.
Вам необходимо заполнить массив перед его использованием (или ожидать, что он будет заполнен нулевыми ссылками).
Обратите внимание, что это вело бы себя точно так же в C#.
Обновлено: Поскольку на самом деле никто не опубликовал код населения, который еще будет работать, вот он:
Class Deck
Public cards(51) As Card
Public Sub New()
For i As Integer = 0 To cards.Length-1
cards(i) = New Card()
Next
End Sub
End Class
Я надеялся, что будет использован пустой конструктор для Card, но, видимо, его игнорируют.
Да, это будет проигнорировано. Как я уже сказал, это то же самое для VB и C# - создание массива никогда не заполняет его, вы всегда получаете значения по умолчанию.
Теперь, когда я смотрел на это достаточно долго, это имеет смысл. Вы никогда не сможете инициализировать элементы поля во время объявления прямо или в данном случае косвенно. Спасибо за помощь
Слишком поздно для v4, но я хотел бы увидеть возможность автоматического вызова конструктора для каждого элемента в массиве, встроенном в .Net 5: возможно, используя синтаксис вроде: Public cards (51) As New Card
Вам нужно сделать что-то
For Each currentItem As String in Me.face
currentItem = "Blank"
End
Приносим извинения, если синтаксис for-each отключен, я обычно использую C#. Но основная проблема в том, что вы не инициализировали каждый элемент массива.
Хорошая работа: правильно составили 51: большинство программистов на C# поместили бы туда 52.