我有一个基类DtaRow,它有一个包含数据的内部字符串数组。我有几十个DtaRow子类,比如UnitRow和AccountRow,他们唯一的目的是提供属性来检索值,这样你就可以aUnit.Name
代替aUnit.pFields(3)
。
我还有一个包含Friend pRows As New Dictionary(Of Integer, DtaRow)
的DtaTable对象。我通常不会将DtaRows插入DtaTable,我插入像UnitRows和AccountRows这样的子类。任何给定的表中只有一种类型。
在app的主要部分我有一个访问者:
Public Readonly Property Units() As IEnumerable
Get
Return Tables(5).pRows.Values 'oh oh oh oh table 5, table 5...
End Get
End Property
这显然会返回DtaRows列表,而不是UnitRows,这意味着我无法做MyDB.Units(5).Name
,这是最终目标。
显而易见的解决方案是将Dim ret As New UnitRow()
和DirectCast一切都放入其中,但随后我将一直构建数千个新阵列。 Uggg。或者我可以把DirectCast放到任何地方我拿出一个值,也是uggg。
我看到有一个名为Array.ConvertAll的方法看起来可能就像我想要的那样。但也许这只是为我做循环并没有真正保存任何东西?如果这是我想要的,我真的不明白如何在其中使用DirectCast。
希望我只是错过了其他一些可以满足我想要的API,但如果没有,那么这里最好的解决方案是什么?我怀疑我需要......
答案 0 :(得分:1)
您可以使用ConvertAll将数组转换为其他类型。
Dim arr(2) As A
Dim arr2() As B
arr(0) = New B
arr(1) = New B
arr(2) = New B
arr2 = Array.ConvertAll(arr, Function(o) DirectCast(o, B))
Class A
End Class
Class B
Inherits A
End Class
在你的情况下,我认为它看起来像这样
Return Array.ConvertAll(Tables(5).pRows.Values, Function(o) DirectCast(o, UnitRow))
请注意,每次都会创建一个新数组。
答案 1 :(得分:1)
您可以根据所需的字段将对象强制转换为list(Of String)
。
Return Tables(5).pRows.Values.Cast(Of DtaRow).Select(Function(r) r.name).ToList
答案 2 :(得分:0)
YES!我走了非线性。这只适用于OOP ......
我的最终目标是将集合中的对象作为特定类型返回,因为我知道我首先将该类型放在那里。当然,我可以从集合中获取价值并对其进行CType,但这很难看 - 尽管在C#中我会非常高兴,因为语法更好。
等等......从集合中检索行的方法是在集合类中,而不是DtaRow的各个子类。所以这就是我所做的......
Public ReadOnly Property Units() As IEnumerable
Get
Return Tables(dbTblUnits).pRow.Values
End Get
End Property
Public ReadOnly Property Units(ByVal K as Integer) As UnitRow
Get
Return DirectCast(Tables(dbTblUnits)(K), UnitRow)
End Get
End Property
Public ReadOnly Property Units(ByVal K as String) As UnitRow
Get
Return DirectCast(Tables(dbTblUnits).Rows(K), UnitRow)
End Get
End Property
为什么这样才能解决问题?通常,如果有人......
Dim U as UnitRow = MyDB.Units(K)
它将调用第一个方法(这是我原来的所有方法),它将返回字典中的.Values,然后调用默认属性返回.Item(K)。但是由于方法调度程序的工作方式,如果我提供更接近匹配参数的更具体的版本,它将调用它。所以我提供了与执行转换的子类相对应的覆盖。
现在这并不完美,因为如果我只是调用单位来获取整个列表,当我从中拉出行时,我仍然需要投射它们。但人们期待,所以在这种情况下这是完全可以接受的。更好的是,当我在VBA中打开这个DLL时,只有第一个这样的方法可见,它返回整个集合,这意味着Units(k)将调用DtaTable上的Default属性,返回DtaRow,但是&#39在VBA很好。
OOP救援!