了解Array.ConvertAll,我可以DirectCast吗?

时间:2015-05-28 15:31:34

标签: vb.net typeconverter

我有一个基类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,但如果没有,那么这里最好的解决方案是什么?我怀疑我需要......

  • 在每个DtaRow子类中进行扩展转换?
  • 或DtaTable中做同样事情的东西?

3 个答案:

答案 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救援!