将对象设置为自身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

所以当我运行这段代码时,我得到一个对象引用集错误,只要属性的第一个名称被设置(第一个属性)…我似乎制造了某种悖论……我试图在它存在之前设置它,但要使它存在,我需要先填充它。

我使用的方法需要是通用的,因为它与一堆不同的对象一起工作,这就是为什么我返回一个对象。

我过去也做过类似的事情,但是使用了实体框架和实体内置于MVC表单模型中的实体,但在这种情况下,我有两个不同的对象,所以没有问题。

现在我的convertStringToObject方法是关闭的,我只是调用它,并将它转换为我想要的对象,但我真的想在一个基类中有它,让其他对象继承它,并使用一个新的构造函数。代码看起来像:

dim person as new Person 
person = TryCast(ConvertStringToObject(dataString,person), Person)

同样不是很多代码,但仍然希望通过新的构造函数在类内部进行转换…

任何想法都将非常感激!

谢谢。

在这种情况下,当对象的构造是一个复杂的或耗时的任务时,我们应用工厂模式或构建器模式。对于您想要完成的任务,Builder模式是完美的匹配。person类携带大量数据(用于这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 string from mainframe
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

希望对你有帮助。

相关内容

  • 没有找到相关文章

最新更新