【问题标题】:VB.NET: How to compare different generic listsVB.NET:如何比较不同的通用列表
【发布时间】:2011-03-02 11:20:53
【问题描述】:

我有一个方法,我正在获取一个通用对象并使用TypeOf 来检查已通过的内容。现在我想将List(Of T) 传递给它(T 是任何东西),无论 T 是什么,我都想对这个列表做同样的事情。我尝试了以下方法:

public sub foo(ByVal obj As Object)
    if TypeOf obj Is List(Of Object) Then
         'do stuff
    end if
end sub

但是,如果我通过 List(Of String),这似乎不起作用。我想List(Of Object)List(Of String) 被视为不同的对象,但我认为由于String 是一个对象,因此比较可能会起作用。

现在我意识到这和 sin 一样丑陋,我最好重载方法以将 List(Of T) 作为其参数,但我主要是出于好奇:有没有比较类型的方法 @ 987654329@ 和 List(Of Object2) 并得到肯定的结果,因为它们都只是 List(Of T)?

【问题讨论】:

  • 呃,如果列表包含不同的类型,你打算如何比较它们?我不明白利用泛型和接受List(Of T) 有什么问题。
  • “不管 T 是什么,我都想对这个列表做同样的事情”——那是什么?

标签: .net vb.net generics generic-list


【解决方案1】:

要检查对象是否为List(of T)类型,无论T是什么类型,都可以使用Type.GetGenericTypeDefinition(),如下例所示:

Public Sub Foo(obj As Object)
    If IsGenericList(obj) Then
        ...
    End If
End Sub    

...

Private Function IsGenericList(ByVal obj As Object) As Boolean
    Return obj.GetType().IsGenericType _
           AndAlso _
           obj.GetType().GetGenericTypeDefinition() = GetType(List(Of ))
End Function

或者作为扩展方法:

Public Sub Foo(obj As Object)
    If obj.IsGenericList() Then
        ...
    End If
End Sub

...

Imports System.Runtime.CompilerServices

Public Module ObjectExtensions
    <Extension()> _
    Public Function IsGenericList(obj As Object) As Boolean
        Return obj.GetType().IsGenericType _
           AndAlso _
           obj.GetType().GetGenericTypeDefinition() = GetType(List(Of ))
    End Function
End Module

【讨论】:

    【解决方案2】:

    List(Of Object)List(Of String) 不同的类型。您可以用它们做不同的事情 - 例如,您不能将 Button 添加到 List(Of String)

    如果您使用的是 .NET 4,则可能需要考虑检查 IEnumerable(Of Object),然后泛型协方差会对您有所帮助。

    你有什么理由不把Foo 本身变成通用的吗?

    【讨论】:

    • @jon-skeet 没有理由不让它通用(这就是我所做的)。所以List(Of String)List(Of Object) 是不同的类型,但它们仍然都是List(Of T)。那么List(Of T) 是某种类型的蓝图吗?
    • 既然你提议IEnumerable(Of Object) -- 为什么不简单地使用非泛型IEnumerable
    • @geekchic:是的,有点。很难描述像 cmets 中的泛型这样的巨大功能 - 我强烈建议仔细阅读 MSDN 或买一本好书。
    • @stakx:是的,IEnumerable 是另一种可能性。
    【解决方案3】:

    很难准确地说出您要完成什么。我读心术很差,所以我想我会让其他几个人先尝试回答这个问题。看起来他们的解决方案不是您要寻找的灵丹妙药,所以我想我会试一试。

    我怀疑这实际上是您正在寻找的语法:

    Public Sub Foo(Of T)(ByVal myList As List(Of T))
        ' Do stuff
    End Sub
    

    这使Foo 成为一个通用方法,并确保您作为参数传入的对象(在本例中为myList)始终是通用列表(List(Of T)) .您可以在myList 参数上调用由List(Of T) 实现的任何方法,因为它保证是正确的类型。真的不需要像 Reflection 这样复杂的东西。

    【讨论】:

      猜你喜欢
      • 2019-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多