对象是作为超类创建的,希望将其转换为子类

时间:2015-01-14 20:10:51

标签: vb.net casting isa-swizzling

我获得了一个包含通用数据对象的库,包括Projects,Tables,Rows和Fields。在我的程序中,我有一个名为Building的项目,其表1包含" Units",表1的字段1是" Unitname"。所以我做的是......

Public Class Unit
  Private myRow As Row
  Public Sub New(ByRef R as Row)
    myRow = Row
  End Sub
  Public Function Unitname() as String
    Return myRow.Fields(1)
  End Function
  ... etc ...
End Class

这看起来不是很糟糕吗?但我没有加载Unit对象,我有行。那么我还要做另一个班......

Public Class Building
  Private myProj as Project
...
  Public Function Units() As List(Of Unit)
    Dim ans as New List(Of Unit)
    For Each R In myProj.Tables(1).Rows
      ans.Add(new Unit(R))
    Next
    Return ans
    ' or I could use myProj.Tables(1).Rows.ConvertTo(Of Unit)
 End Function
 ...etc...

当然,我必须列出建筑物列表,这样我才能进入单位列表,以及其他几十个列表和访问者,转而成为数千行代码,这些代码的唯一目的就是制作一组指向另一组的对象。

它有效,我知道送货是一个功能。但我真正想做的是制作一个看起来像......的单位。

Public Class Unit
  Inherits Row
  ...
End Class

然后我会"反向演员"将List(Of Row)列入List(Of Unit)。这不仅可以消除大量代码,还可以消除悬空指针,减少大量内存,并消除可能需要一些时间的设置集。从理论上讲,除了代码之外没有区别,但我没有看到在VB.Net中做到这一点的方法。

在Obj-C中,这称为swizzling(和/或扩展),我认为Java有类似的概念。我怀疑ADO.Net必须做这样的事情?是否有某种"将其包裹在那个"我缺少哪些功能?

2 个答案:

答案 0 :(得分:0)

节省大量时间并使用DataSet。对于数据库应用程序,面向对象编程不能很好地工作。 DataSet只能在内存中,不需要数据库引擎。

Dim dsProject As New DataSet("Project")
Dim dtUnits As New DataTable("Units")
dtUnits.Columns.Add("Unitname", GetType(String))
dtUnits.Columns.Add("Address", GetType(String))
dsProject.Tables.Add(dtUnits)
dtUnits.Rows.Add("Unit 1", "1 Test Street")
dtUnits.Rows.Add("Unit 2", "2 Sample Avenue")
dtUnits.Rows.Add("Unit 3", "3a Demo Road")

Dim drMatch() As DataRow = dtUnits.Select("Unitname='Unit 1'")
If drMatch.GetUpperBound(0) >= 0 Then
  MsgBox(drMatch(0).Item("Address"))
Else
  MsgBox("No matching record")
End If

答案 1 :(得分:0)

如果您不想使用DataSet,可以尝试共享转换器功能:

  Class unit
    Inherits row

    Public Property UnitName() As String
      Get
        Return fields(1)
      End Get
      Set(ByVal value As String)
        fields(1) = value
      End Set
    End Property

    Shared Function UnitToRow(u As unit) As row
      Return DirectCast(u, row)
    End Function

    Shared Function RowToUnit(r As row) As unit
      Dim u As New unit
      u.fields = r.fields
      Return u
    End Function

  End Class

  Sub usage()
    Dim lstR As New List(Of row) '<--- source data

    Dim lstU As List(Of unit) = lstR.ConvertAll(New Converter(Of row, unit)(AddressOf unit.RowToUnit))
    MsgBox(lstU(0).UnitName)

    lstU(0).UnitName = "xxx"

    Dim lstR2 As List(Of row) = lstU.ConvertAll(New Converter(Of unit, row)(AddressOf unit.UnitToRow))
    MsgBox(lstR2(0).fields(1))

  End Sub