2

我的情况很奇怪。我有大量相互派生的类,并且我将对象存储在各种集合中。

例如:

Record <-- CostRecord <-- AccruedCostRecord
                      <-- PrepaidCostRecord
                      <-- StockRecord

对象存储在 List(Of Record) 中,我想在特定列表中搜索给定类型的记录。

    Private Function findRecord(listToSearch As List(of Record), recordName As String, recordType As Type) As Record
        For i As Integer = 0 To listToSearch.Count - 1
            If listToSearch(i).name.equals(recordName)
                'If record is of type "recordType" then return it
            End If
        Next
    End Function

通常我会使用“TypeOf ... Is”运算符,因为我也对基类类型感兴趣。因此,如果我传入“CostRecord”,我希望检索 AccruedCostRecord、PrepaidCostRecord 或 StockRecord。

在这种情况下,我不能使用 TypeOf 因为它不接受 System.Type 作为参数,而且我想不出另一种方式来告诉它我想要什么。

我也不相信“GetType”会在这里帮助我,因为我对基类感兴趣。

有人有什么想法吗?也许某种疯狂的反射魔法?

谢谢

4

3 回答 3

1

我会用 LINQ 重写它,但作为快速回答,你可以这样做:

Private Function findRecord(listToSearch As List(of Record), recordName As String, recordType As Type) As Record
    For i As Integer = 0 To listToSearch.Count - 1
        If listToSearch(i).name.equals(recordName) And listToSearch(i).GetType() = recordType Then
            ' ...
        End If
    Next
End Function

关键是这个比较:listToSearch(i).GetType() = recordTypeGetType()方法(继承自Object)将返回对象类型Type(然后与您的参数进行比较)。通过严格比较,它只会匹配给定类型的对象(如果你指定PrepaidCostRecordrecordType只会匹配那个,如果你指定CostRecord那么它不会匹配任何东西)。

要包含派生类(例如,您可以CostRecord为参数指定,recordType它会匹配所有派生类,PrepaidCostRecord但不匹配祖先类Record),您只需将其更改为:

recordType.IsAssignableFrom(listToSearch(i).GetType())

最终代码将是:

Private Function findRecord(listToSearch As List(of Record), recordName As String, recordType As Type) As Record
    For i As Integer = 0 To listToSearch.Count - 1
        If listToSearch(i).name.equals(recordName) And recordType.IsAssignableFrom(listToSearch(i).GetType()) Then
            ' ...
        End If
    Next
End Function

现在是时候用 LINQ 重写它了,例如:

Dim records = From record In listToSearch_
    Where record.name.equals(recordName) And recordType.IsAssignableFrom(record.GetType)

在您的情况下,您可以将其改写为更短:

Private Function findRecord(listToSearch As List(of Record), recordName As String, recordType As Type) As Record
    findRecord = listToSearch.FirstOrDefault(Function(r) r.name.equals(recordName) And recordType.IsAssignableFrom(r.GetType))
End Function
于 2013-11-06T09:48:25.290 回答
1

.IsAssignableFrom您可以在您的类型上使用该方法:

If recordType.IsAssignableFrom(listToSearch(i).GetType())

例如,如果您的列表项是AccruedCostRecord并且您的recordTypeCostRecord,这将返回True

于 2013-11-06T09:48:42.433 回答
-1

您可以使用 GetType.BaseType 查看基类型是否是您要查找的类。如果没有,您可以更深入地了解 Gettype.Baseytpe.BaseType。

于 2013-11-06T09:53:14.787 回答