![](/img/trans.png)
[英]VB.NET throwing “Object reference not set to an instance of an object” Exception
[英]Set Object to instance of itself VB.NET
我现在正在使用一个测试对象,作为一个非常大的对象(大约700个属性)的概念证明。
基本上,我要尝试的是使用新的构造函数在对象中设置数据,而无需手动设置属性,因为有太多的属性。 例如
Person.Name = "Bob"
Person.Age = 30
etc...
相反,我想做的是通过反射遍历对象中的属性并设置对象中的属性。 数据是从大型机中传入的巨大字符串。
Private _person As Person
Public Sub New(ByVal personData As String)
_person = TryCast(ConvertStringToObject(personData, Me.GetType), Person)
End Sub
Public Property FirstName As String
Get
Return _person.FirstName
End Get
Set(ByVal value As String)
_person.FirstName = value
End Set
End Property
Private Function ConvertStringToObject(ByVal data As String, ByVal obj As Object) As Object
Dim objectType As Type = obj.GetType
Dim properties As PropertyInfo() = objectType.GetProperties
For Each objProperty As PropertyInfo In properties
'just an example... not really how i get data...
Dim value As String = data.Substring(0, 10)
objProperty.SetValue(obj, value, Nothing)
Next
Return obj
End Function
因此,当我运行此代码时,只要设置了属性名(第一个属性),我就会收到一个对象引用设置错误……似乎我已经创建了一种悖论……我试图在此之前进行设置它存在,但要使其存在,我需要先填充它。
我使用的方法必须是通用的,因为它与许多不同的对象一起使用,这就是为什么我要返回一个对象。
过去我做过类似的事情,但是将来自实体框架的and实体内置到MVC表单的模型中,但是在那种情况下,我有两个不同的对象,所以没有问题。
就目前而言,我的convertStringToObject方法本身是关闭的,我只是调用它并将其强制转换为想要的对象,但我真的很想将其放在基类中,让另一个对象继承它并使用新的构造方法。 所以代码看起来像:
dim person as new Person
person = TryCast(ConvertStringToObject(dataString,person), Person)
再次不是很多代码,但是仍然希望通过新的构造函数在类内部进行转换...
任何想法将不胜感激!
谢谢。
在这种情况下,当对象的构造是复杂的或耗时的任务时,我们将采用工厂模式或构建器模式。 对于您要完成的任务,Builder模式是完美的选择。 佩森(Peson)类正在承载大量数据(针对这700个属性)。 因此,我们还需要将数据传输与业务模型验证脱钩。 这是操作方法:
Class PersonData
Public Name as String
Public Age as integer
...
...and 700 more...
End Class
Class person
private _personData as PersonData = nothing
sub new(personData as PersonData)
_personData = personData
end sub
property Name as string
get
return _personData.Name
end get
set(value as string)
...the validations here...
_personData.Name = value
end set
end property
End Class
MustInherit Class PersonBuilder
protected _stringRepresentation as String
sub setString(stringRep as string)
_stringRepresentation = stringRep
end sub
function BuildPerson as Person
end class
一种构建具体实例的方法是使用大型机中的loooong字符串
class MainFramePersonBuilder
inherits PesonBuilder
overrides function BuildPerson as Person
dim pData as PersonData
pData = DeserializeMainFrameString(_stringRepresentation)
return new Person(pData)
end sub
private function DeserializeMainframeString(mString as string) as personData
... do the reflection stuff here...
... dont use person class direcctly...
... rather use the PersonData structure...
return thePersonData
end sub
另一种方法是使用从某些Web服务获取的数据来做到这一点,我知道它不在范围内,但是如果满足此要求,则此体系结构将有所帮助。
class JSONPersonBuilder
inherits PersonBuilder
overrides function BuildPerson as person
return new Person(DeserializeJSONString(_stringRepresentation))
end function
end class
dim pb as PersonBuilder = new MainFramePersonBuilder() 'JSONPersonBuilder
pb.setString(mainFrameString) ' JSONString
dim p as Person = pb.BuildPerson()
现在,如果您需要通过网络或您自己的Web服务将Person
转移到其他地方,则无需发送mainFrameString。 序列化PersonData并发送它。 您将把客户端与服务器隔离-您的PersonData是中间层。
无需使用私有变量来保存当前的对象实例,而是已有一个可用变量Me
。 以下是调整后的代码,该代码使用Me
作为设置其属性值的目标:
Public Sub New(ByVal personData As String)
ConvertStringToObject(personData)
End Sub
Public Property FirstName As String
Private Sub ConvertStringToObject(ByVal data As String)
Dim objectType As Type = Me.GetType
Dim properties As PropertyInfo() = objectType.GetProperties
For Each objProperty As PropertyInfo In properties
'just an example... not really how i get data...
Dim value As String = data.Substring(0, 10)
objProperty.SetValue(Me, value, Nothing)
Next
End Function
希望能有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.