【问题标题】:How do I use generics in VB.NET?如何在 VB.NET 中使用泛型?
【发布时间】:2011-08-17 13:47:46
【问题描述】:

我有以下代码:

Public Shared Function GetListAsString(ByVal data As List(Of String)) As String
    Dim retVal As String = "| "
    For Each obj As String In data
        retVal = retVal + obj.ToString() + " |"
    Next
    Return retVal
End Function

它将列表转换为可打印的字符串。现在它已设置为与 just 列表一起使用。我觉得它应该能够与任何类型的 Collection 一起工作。我是集合和泛型的新手。当我尝试做类似的事情时

Public Shared Function GetListAsString(ByVal data As Collection(T)) As String
    Dim retVal As String = "| "
    For Each obj As String In data.ToString()
        retVal = retVal + obj.ToString() + " |"
    Next
    Return retVal
End Function

我得到一个错误。谁能指出我正确的方向?

【问题讨论】:

  • 你得到什么错误?
  • Error 1 Array bounds cannot appear in type specifiers.
  • 您使用哪个 .Net Framework 版本? string.Join("|", list) 已经做了你想做的事,至少在 .Net Framework 4.0 中

标签: .net vb.net generics


【解决方案1】:

您没有从编译器获得非常有用的错误消息。你忘记了使函数通用,它不能产生一个像样的诊断。让我们关注更大的问题:

    For Each obj As String In data.ToString()
        retVal = retVal + obj.ToString() + " |"
    Next

For 循环被破坏,从 data.ToString() 开始。只用数据。并且数据的元素类型是T,而不是String。此外,由于您只是枚举集合,您可以使用较小的接口 IEnumerable,使其适用于更多集合类型。因此:

Public Shared Function GetCollectionAsString(Of T)(ByVal data As IEnumerable(Of T)) As String
    Dim retVal As String = "| "
    For Each obj As T In data
        retVal = retVal + obj.ToString() + " |"
    Next
    Return retVal
End Function

注意函数名称后添加的(Of T),它可以解决您原来的错误消息。

【讨论】:

    【解决方案2】:

    Collection(T) 应该是IEnumerable(Of T)

    更新顺便说一句,顺便说一句,只要你想从你的集合对象中得到ToString,并且ToStringObject类中定义并且所有其他类都继承Object,你可以用

    Public Shared Function GetListAsString(ByVal data As IEnumerable(Of Object)) As String
    

    【讨论】:

    • 好像是这样的,让我测试一下
    • 这是您最好的选择,因为您的目标是让您的函数适用于最广泛的集合。 IEnumerable(of T) 适用于大多数(全部?)集合类,包括数组。
    • @user489041 我不确定,但我认为您必须将 (Of T) 添加到函数声明中,如 Daniel A. White suggests。无法确定,从未亲自尝试过。
    【解决方案3】:

    您需要在方法签名上指定泛型。

    Public Shared Function GetListAsString(Of T)(ByVal data As ICollection(Of T)) As String
    

    编辑我改了。

    【讨论】:

    • 我试了一下,它给了我一个错误 Microsoft.VisualBasic.Collection 没有类型参数,因此不能有类型参数。它在Collection(Of T) 中有下划线的 T
    • ICollectionIEnumerable 的后代类,IEnumerable 适用于该任务,因此无需使用ICollection
    • 当然,但他在原帖中使用的是Collection
    【解决方案4】:

    得益于 VB.Net 推理的魔力,解决方案相同,但代码更少:

    Public Shared Function GetListAsString(Of T)(ByVal data As IEnumerable(Of T)) As String
        Dim retVal = "| "    
        For Each obj In data
            retVal &= obj.ToString + " |"
        Next
        Return retVal
    End Function
    

    编辑

    或者使用 String.Join 甚至更简单...

    Public Shared Function GetListAsString(Of T)(ByVal data As IEnumerable(Of T)) As String
        Return "| " & String.Join(" |", data) & " |"
    End Function
    

    【讨论】:

    • 编辑:添加了一个带有 String.Join 的版本
    【解决方案5】:

    Hans's answer 的缩短版,使用扩展方法代替显式 For Each 循环:

    Public Function GetListAsString(Of T)(ByVal data As IEnumerable(Of T)) As String
        Return data.Aggregate("| ", Function(d, s) d & s.ToString & " |")
    End Function
    

    但是你有没有尝试过来自 cmets 的 Snowbear 的建议?

    "| " & String.Join(" | ", data) & " |"
    

    这个String.Join 代码的行为确实与您问题中的代码略有不同,但它是如此简单。以下是区别

    empty-sequence -> "| |" rather than "| "
    1, 2 -> "| 1 | 2 |" rather than "| 1| 2 |" (was that really what you meant?)
    

    【讨论】:

    • 在 James Michael Hare 的优秀博客上的 post 中了解有关 String.Join 的更多信息
    猜你喜欢
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多