提问人:user9671207 提问时间:10/25/2018 最后编辑:Joel Coehoornuser9671207 更新时间:10/26/2018 访问量:1792
VB.net 类对象引用未设置为对象的实例
VB.net Class Object reference not set to an instance of an object
问:
我知道这个问题以前被问过很多次,但在阅读了所有回复后,我就是无法解决。我不知道我做错了什么,现在已经看了 2 天了。 我有一个嵌套类,只是试图为它赋值,但我不断收到此错误。调试并没有让我走得更远。
我的类定义:
Public Class DocumentHeader
Private _username As String
<JsonProperty("username")> _
Public Property username() As String
Get
Return _username
End Get
Set(ByVal value As String)
_username = value
End Set
End Property
Private _bus_act As String
<JsonProperty("bus-act")> _
Public Property bus_act() As String
Get
Return _bus_act
End Get
Set(ByVal value As String)
_bus_act = value
End Set
End Property
Private _ref_doc_no As String
<JsonProperty("ref-doc-no")> _
Public Property ref_doc_no() As String
Get
Return _ref_doc_no
End Get
Set(ByVal value As String)
_ref_doc_no = value
End Set
End Property
Private _header_txt As String
<JsonProperty("header-txt")> _
Public Property header_txt() As String
Get
Return _header_txt
End Get
Set(ByVal value As String)
_header_txt = value
End Set
End Property
Private _comp_code As String
<JsonProperty("comp-code")> _
Public Property comp_code() As String
Get
Return _comp_code
End Get
Set(ByVal value As String)
_comp_code = value
End Set
End Property
Private _pstng_date As String
<JsonProperty("pstng-date")> _
Public Property pstng_date() As String
Get
Return _pstng_date
End Get
Set(ByVal value As String)
_pstng_date = value
End Set
End Property
Private _trans_date As String
<JsonProperty("trans-date")> _
Public Property trans_date() As String
Get
Return _trans_date
End Get
Set(ByVal value As String)
_trans_date = value
End Set
End Property
Private _fis_period As String
<JsonProperty("fis-period")> _
Public Property fis_period() As String
Get
Return _fis_period
End Get
Set(ByVal value As String)
_fis_period = value
End Set
End Property
Private _doc_date As String
<JsonProperty("doc-date")> _
Public Property doc_date() As String
Get
Return _doc_date
End Get
Set(ByVal value As String)
_doc_date = value
End Set
End Property
Private _doc_type As String
<JsonProperty("doc-type")> _
Public Property doc_type() As String
Get
Return _doc_type
End Get
Set(ByVal value As String)
_doc_type = value
End Set
End Property
End Class
这是我的主要课程:
Public Class RootObjectInvoice
Private _document_header As DocumentHeader
Public Property document_header() As DocumentHeader
Get
Return _document_header
End Get
Set(ByVal value As DocumentHeader)
_document_header = value
End Set
End Property
End Class
到目前为止,我认为一切都很好。
现在是我的代码:
Dim Root As RootObjectInvoice
Dim Document_Header As DocumentHeader
Root = New RootObjectInvoice
Document_Header = New DocumentHeader
Try
Document_Header = Root.document_header
Document_Header.bus_act = "AAAA"
在这条线上,我得到了.我在这里缺少一些关于如何初始化对象的内容。
任何意见将不胜感激。Document_Header.bus_act = "AAAA"
NullpointerException
由于现在有效,我在以下方面遇到了问题(我习惯了 C#,而不是 VB) 我将此属性添加到 RootObjectInvoice 中
Private _metadata As List(Of Metadata)
Public Property metadata() As List(Of Metadata)
Get
Return _metadata
End Get
Set(ByVal value As List(Of Metadata))
_metadata = value
End Set
End Property
然后尝试初始化它:
Dim Meta_Data() As List(Of Metadata)
Root.metadata() = New List(Of Metadata)
Meta_Data = Root.metadata
但是最后一行给了我以下错误:
“System.Collections.Generic.List(Of Metadata)”类型的值不能转换为“System.Collections.Generic.List(Of Metadata)的一维数组”。
答:
当然,这句话:
Document_Header = Root.document_header
应该是相反的,即
Root.document_header = Document_Header
顺便说一句,提供这样的属性的完整实现是没有意义的:
Private _document_header As DocumentHeader
Public Property document_header() As DocumentHeader
Get
Return _document_header
End Get
Set(ByVal value As DocumentHeader)
_document_header = value
End Set
End Property
当你可以这样做时:
Public Property document_header() As DocumentHeader
并实现同样的事情。仅当需要执行除 get 和设置支持字段以外的其他操作(例如验证新值或引发事件)时,才应提供完整的实现。
评论
类型是 ,类是引用类型。所以看看这行代码:DocumentHeader
Class
Private _document_header As DocumentHeader
这里,是引用类型的变量;它希望在内存中保存对对象的引用。这是错误消息的“对象引用”部分。但此时,变量的值仍为 or 。该代码还用属性包装了该变量,但这并没有真正改变任何内容。_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
现在,我们的变量引用一个实例,并且该类型具有 type 的属性。Root
RootObjectInvoice
RootObjectInvoice
document_header
DocumentHeader
但是document_header
属性仍然没有价值! 创建引用类型的新
实例不会自动为该类型的引用属性或成员创建实例。 仍为 null/Nothing。Root.document_header
接下来我们有了这段代码:
Document_Header = Root.document_header
Document_Header.bus_act = "AAAA"
因此,我们有一个名为 reference 变量的变量,它没有设置为对象的实例。我们将这个空引用分配给变量......这会丢弃刚刚创建的实例。哎呀;真是浪费。然后,我们尝试访问该空引用上的属性。Root.document_header
Document_Header
这就是让事情爆炸并抛出异常的原因。
您有一个名为的对象引用变量,该变量不再分配任何值。您之前创建和分配的对象实例已被丢弃,并且不再设置。然后,您尝试取消引用此变量,以便可以访问属性,但那里什么都没有。Document_Header
所以你有这个问题:
我在这里缺少一些关于如何初始化对象的内容。
您可以这样做:
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()
Dim Meta_Data As List(Of MetaData)
仅对数组或 Property 声明使用括号。此外,您希望此变量实际引用 New 对象。你可以把它放在与声明相同的行上:
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
您仍然可以使用该属性来执行您期望的所有操作,包括添加新项,即使没有 .你唯一不能做的就是从类下完全改变集合;不能为属性分配其他 List 实例。同样,在 C# 中,定义 List 属性通常是更好的做法,如下所示:Set
private List<Metadata> _metadata = new List<Metadata>();
public List<Metadata> metadata
{
get {return _metadata;}
}
从 C# 6 开始,您甚至可以这样做:
public List<Metadata> metadata {get;} = new List<Metadata>();
评论
documentHeader
Document_Header
DocumentHeader
document_header
Meta_Data
Dim Meta_Data As List(Of Metadata)
Dim Meta_Data() As List(Of Metadata)