【问题标题】:Object was created as a superclass, want to turn that into a subclass对象是作为超类创建的,想把它变成子类
【发布时间】:2015-01-14 20:10:50
【问题描述】:

我得到了一个库,其中包含通用数据对象、项目、表、行和字段。在我的程序中,我有一个名为 Building 的项目,它的表 1 包含“单位”,表 1 的字段 1 是“单位名称”。所以我所做的是......

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

看起来还不错吧?但是我没有加载单元对象,我有行。那我也得另开一门课了……

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 必须做这样的事情?我缺少某种“将其包装在其中”的功能吗?

【问题讨论】:

  • 如果这些是数据集,您是否考虑过使用强类型数据集?
  • 这些不是DataSet,都是一堆读取文本文件的代码。

标签: vb.net casting isa-swizzling


【解决方案1】:

使用 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

【讨论】:

  • 也许我误解了这个例子......我要解决的问题是数据已经完全读入,并作为一堆List(Of String)传回给我。使用此解决方案似乎必须将这些项目复制到 DataRow 中,这正是我对自己的类所做的事情。我在这里错过了一些魔法吗?
  • 是的,我建议您放弃自己的自定义对象模型,而使用内置的System.Data 对象。优点是您不需要编写太多代码,并且可以更好地与内置数据控件等集成。当然,您可能不想这样做。
  • 我还建议您放弃通用对象库,因为对象的名称(表、行、字段)暗示它们在模仿数据库对象模型。
  • 这正是它所做的——它使用 XLS 文件来模拟数据库。现在在你说“你为什么不...”之前,答案是这个库的速度是 MS 解决方案的 1,000 到 5,000 倍。不是开玩笑,相信我,我们已经测试过了。
【解决方案2】:

如果您不想使用 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

【讨论】:

  • 啊,我想这就是我要找的。我会玩这个。
猜你喜欢
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多