Тип DocumentHeader
- это Class
, а классы - ссылочные типы .Посмотрите на эту строку кода:
Private _document_header As DocumentHeader
Здесь _document_header
- переменная для ссылочного типа;он хочет хранить ссылку на объект в памяти.Это часть «Ссылка на объект» сообщения об ошибке.Но в настоящее время значение переменной все еще равно null
или Nothing
.Код дополнительно оборачивает эту переменную свойством document_header
, но это ничего не меняет.
Позже у нас есть этот код:
Dim Root As RootObjectInvoice
Dim Document_Header As DocumentHeader
Root = New RootObjectInvoice
Document_Header = New DocumentHeader
Мы видим переменную Root
типа RootObjectInvoice
.Мы также создаем экземпляр этого типа и назначаем его переменной, и мы создаем экземпляр типа заголовка Document_Header
, который обсуждался ранее, и назначаем его отдельной переменной.
Теперь наша переменная Root
ссылается на экземпляр RootObjectInvoice
, а тип RootObjectInvoice
имеет свойство document_header
типа DocumentHeader
.
Но свойство document_header
по-прежнему не имеет значения! Создание New
экземпляра ссылочного типа не приводит к автоматическому созданию экземпляра для ссылочных свойств или членов типа. Root.document_header
по-прежнему равно нулю / ничего.
Далее мы имеемэтот код:
Document_Header = Root.document_header
Document_Header.bus_act = "AAAA"
Итак, у нас есть ссылочная переменная с именем Root.document_header
, которая не установлена для экземпляра объекта.Мы присваиваем эту пустую ссылку переменной Document_Header
, которая отбрасывает только что созданный экземпляр.К сожалению,какая трата.Затем мы пытаемся получить доступ к свойству по этой пустой ссылке.
Вот что заставляет вещи взорваться и вызвать исключение.
У вас есть переменная ссылки на объект с именем Document_Header
, которой больше не присваивается значение .Экземпляр объекта, который вы ранее создали и назначил, был отброшен и больше не задан.Затем вы пытаетесь отменить ссылку на эту переменную, чтобы получить доступ к свойству, но там ничего нет .
Итак, у вас есть вопрос:
I 'м здесь что-то не хватает, как инициализировать объект.
Вы можете сделать это:
Dim Root As New RootObjectInvoice()
Root.document_header = New DocumentHeader()
Или вы можете добавить конструктор или инициализатор в типе RootObjectInvoice
:
Private _document_header As New DocumentHeader
Мне нужно дополнительно обратиться к последующим правкам из-за этой строки:
Dim Meta_Data() As List(Of Metadata)
Дополнительные скобки рядом с Meta_Data()
делают эту переменную array .То, что вы объявили, это массив списков .Вы просто хотите это:
Dim Meta_Data As List(Of MetaData)
Используйте только скобки для массива или Property объявлений.Кроме того, вы хотите, чтобы эта переменная фактически ссылалась на новый объект.Вы можете поместить это вместе в той же строке, что и объявление:
Dim Meta_Data As New List(Of Metadata)()
Так же, как вы могли бы написать следующее в C #:
var Meta_Data = new List<Metadata>();
Но так как вы действительно хотите, чтобы это было частьюпеременной Root
, вы можете полностью пропустить эту промежуточную переменную Meta_Data
:
Root.metadata = New List(Of Metadata)()
Как и в C #, вы могли бы написать:
Root.metadata = new List<Metadata>();
Но на самом деле это плохопрактика.В большинстве случаев, когда класс имеет тип коллекции в качестве свойства элемента, это свойство должно обеспечивать только Get
доступ . Это было верно и в C #.
Вы хотите объявить свойство в классе следующим образом:
Private _metadata As New List(Of Metadata)
Public Property metadata() As List(Of Metadata)
Get
Return _metadata
End Get
End Property
Вы все еще можете использовать свойство, чтобы делать всевы ожидаете, включая добавление новых предметов, хотя Set
нет.Единственное, что вы не можете сделать, это полностью изменить коллекцию из-под класса;Вы не можете назначить другому экземпляру List свойство.Точно так же в C # обычно лучше определять свойство List следующим образом:
private List<Metadata> _metadata = new List<Metadata>();
public List<Metadata> metadata
{
get {return _metadata;}
}
А в C # 6 вы даже можете просто сделать это:
public List<Metadata> metadata {get;} = new List<Metadata>();