使用LINQ提取对象ID拼接逗号分隔字符串遇异常求助
问题:LINQ提取ID拼接字符串返回迭代器类型名称
从自定义对象集合中提取ID并拼接成逗号分隔字符串时,执行LINQ代码后得到的结果是:System.Linq.Enumerable+WhereSelectEnumerableIterator2[item,System.Int32] 而非预期的1,2,3`。
自定义类代码
Public Class Items Implements IEnumerable Private _ID As Integer Private desc As String Private arrItemList As New ArrayList Public Property ID() As Integer Get Return _ID End Get Set(ByVal Value As Integer) _ID = Value End Set End Property Public ReadOnly Property Count() As Integer Get Return arrItemList.Count End Get End Property Public Sub AddProduct(ByVal obj As item) arrItemList.Add(obj) End Sub Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator Return arrItemList.GetEnumerator() End Function End Class Public Class item Public Property ID As Integer Public Property desc As String End Class
当前实现代码
Dim objItems As New Items() objItems.AddProduct(New item With {.ID = 1, .desc = "orange"}) objItems.AddProduct(New item With {.ID = 2, .desc = "apple"}) objItems.AddProduct(New item With {.ID = 3, .desc = "peach"}) Dim query = objItems.Cast(Of item)().Select(Function(o) o.ID) Dim result As String = String.Join(",", query)
问题原因
LINQ查询返回的是延迟执行的迭代器对象,早期版本的String.Join没有针对泛型IEnumerable(Of T)的重载,直接传入迭代器时,会调用对象的ToString()方法返回其类型名称,而非遍历元素进行拼接。
解决方案
将LINQ查询结果转换为具体集合类型(如数组或List),让String.Join能遍历元素拼接:
方法1:转换为数组
Dim objItems As New Items() objItems.AddProduct(New item With {.ID = 1, .desc = "orange"}) objItems.AddProduct(New item With {.ID = 2, .desc = "apple"}) objItems.AddProduct(New item With {.ID = 3, .desc = "peach"}) Dim query = objItems.Cast(Of item)().Select(Function(o) o.ID) Dim result As String = String.Join(",", query.ToArray()) ' 调用ToArray()触发迭代
方法2:转换为List
Dim result As String = String.Join(",", query.ToList()) ' 调用ToList()触发迭代
优化建议
将自定义Items类改为实现泛型IEnumerable(Of item),并使用泛型List(Of item)替代非泛型ArrayList,避免每次查询时的Cast(Of item)操作:
Public Class Items Implements IEnumerable(Of item) Private _ID As Integer Private desc As String Private arrItemList As New List(Of item) ' 替换为泛型List Public Property ID() As Integer Get Return _ID End Get Set(ByVal Value As Integer) _ID = Value End Set End Property Public ReadOnly Property Count() As Integer Get Return arrItemList.Count End Get End Property Public Sub AddProduct(ByVal obj As item) arrItemList.Add(obj) End Sub Public Function GetEnumerator() As IEnumerator(Of item) Implements IEnumerable(Of item).GetEnumerator Return arrItemList.GetEnumerator() End Function ' 显式实现非泛型IEnumerable的GetEnumerator Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator Return GetEnumerator() End Function End Class
优化后的查询代码可简化为:
Dim query = objItems.Select(Function(o) o.ID) Dim result As String = String.Join(",", query.ToArray())
内容的提问来源于stack exchange,提问作者CDVS
相关产品推荐
相关产品推荐

