将Object设置为自己的VB.NET实例

时间:2013-06-08 00:42:52

标签: .net vb.net oop reflection

我现在正在使用一个测试对象作为一个非常大的对象(大约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)

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

非常感谢任何想法!

谢谢。

2 个答案:

答案 0 :(得分:5)

在构建对象是复杂或耗时任务的情况下,我们应用工厂模式或构建器模式。对于您想要完成的任务,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()

现在,如果你需要通过网络或自己的网络服务将Person转移到某个不同的地方,你就不需要发送mainFrameString。序列化PersonData并发送它。您将把您的客户与服务器隔离开来 - 您的PersonData是中间层。

答案 1 :(得分:2)

您已经拥有一个可用的变量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

希望有所帮助。