我有一个基类DtaRow,它有一个包含数据的String内部数组。我有几十个DtaRow的子类,比如UnitRow和AccountRow,它们唯一的目的是提供属性来检索值,这样就可以执行aUnit.Name而不是aUnit.pFields(3)了。
我还有一个DtaTable对象,它包含一个Friend pRows As New Dictionary(Of Integer, DtaRow)。我通常不将DtaRows插入到DtaTable中,而是插入UnitRows和AccountRows这样的子类。任何给定的表都只有一种类型。
在应用程序的主要部分,我有一个访问器:
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的所有内容都包含进去,但之后我一直在构建数千个新的数组。麻瓜。或者,我可以把DirectCast放在任何地方--我拿出一个值,也就是uggg。
我看到有一个叫做Array.ConvertAll的方法,看起来它可能是我想要的。但也许这只是为我做了循环,并没有真正保存任何东西?如果这是我想要的,我真的不明白如何在其中使用DirectCast。
希望我只是错过了其他一些API来做我想做的事情,但是如果失败了,这里最好的解决方案是什么呢?我想我需要..。
发布于 2015-05-28 15:48:34
可以使用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))请注意,这将创建一个新的数组每次。
发布于 2015-05-28 15:49:37
您可以根据需要的字段将对象转换为list(Of String)。
Return Tables(5).pRows.Values.Cast(Of DtaRow).Select(Function(r) r.name).ToList发布于 2015-05-28 18:40:47
是!我变成了非线性的。这只因为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)。但是,由于方法dispatcher的工作方式,如果我提供了一个更符合参数的更具体的版本,它将调用这个版本。因此,我提供了执行强制转换的子类的同级重写。
这并不完美,因为如果我只调用单元来获得整个列表,当我从其中提取行时,我仍然必须将它们投出。但人们希望如此,所以在这种情况下,这是完全可以接受的。更好的是,当我在VBA中打开这个DLL时,只有第一个方法是可见的,这将返回整个集合,这意味着Unit(K)将调用DtaTable上的默认属性,返回一个DtaRow,但这在VBA中很好。
救命啊!
https://stackoverflow.com/questions/30510990
复制相似问题