vb.net linq对象列表

vb.net linq对象列表,vb.net,linq,Vb.net,Linq,在vb.net中,使用linq连接2个对象列表。 两个列表的类型相同 我搜索按Id对两个列表进行分组的最佳方法。 就像一个独特的世界 样本: Imports System.Text Imports System.Reflection Module Module1 Sub Main() Dim list1 As New List(Of Item) For i As Integer = 1 To 4 list1.Add(New It

在vb.net中,使用linq连接2个对象列表。 两个列表的类型相同

我搜索按Id对两个列表进行分组的最佳方法。 就像一个独特的世界

样本:

Imports System.Text
Imports System.Reflection

Module Module1

    Sub Main()
        Dim list1 As New List(Of Item)
        For i As Integer = 1 To 4
            list1.Add(New Item(i, i.ToString))
        Next

        Dim list2 As New List(Of Item)
        For i As Integer = 3 To 6
            list2.Add(New Item(i, i.ToString))
        Next

        Dim list3 As New List(Of Item)
        list3 = (list1.Concat(list2)).ToList
        Console.WriteLine(Item.PrintList(list3).ToString)        

        Console.ReadLine()
    End Sub

End Module

Class Item
    Private _Id As Integer
    Private _Value As String

    Public Property Id() As Integer
        Get
            Return _Id
        End Get
        Set(ByVal value As Integer)
            _Id = value
        End Set
    End Property
    Public Property Value() As String
        Get
            Return _Value
        End Get
        Set(ByVal value As String)
            _Value = value
        End Set
    End Property

    Public Sub New()
    End Sub
    Public Sub New(ByVal id As Integer, ByVal value As String)
        Me.Id = id
        Me.Value = value
    End Sub

    Public Overrides Function ToString() As String
        Dim sb = New Text.StringBuilder()        
        For Each item In [GetType]().GetFields(BindingFlags.NonPublic Or BindingFlags.Instance)
            sb.Append(String.Format("[{0} = {1}] ", item.Name, item.GetValue(Me)))
        Next
        Return sb.ToString()
    End Function

    Public Shared Function PrintList(ByVal myList As List(Of Item)) As StringBuilder
        Dim result As New StringBuilder
        For Each i In myList
            result.AppendLine(i.ToString)
        Next
        Return result
    End Function

End Class
列表3在concat之后包含的内容:

[_Id = 1] [_Value = 1] 
[_Id = 2] [_Value = 2] 
[_Id = 3] [_Value = 3] 
[_Id = 4] [_Value = 4] 
[_Id = 3] [_Value = 3] 
[_Id = 4] [_Value = 4] 
[_Id = 5] [_Value = 5] 
[_Id = 6] [_Value = 6] 
我们想要的是:

[_Id = 1] [_Value = 1] 
[_Id = 2] [_Value = 2] 
[_Id = 3] [_Value = 3] 
[_Id = 4] [_Value = 4] 
[_Id = 5] [_Value = 5] 
[_Id = 6] [_Value = 6] 
我搜索按Id对两个列表进行分组的最佳方法 与众不同

使用

但是,您需要首先覆盖类
项中的
Equals
GetHashCode
。然后所有Linq方法都将使用您的ID:

Class Item
    Public Property ID As Int32

    Public Overrides Function Equals(obj As Object) As Boolean
        If obj Is Nothing Then Return False
        If Not TypeOf obj Is Item Then Return False
        Return Id = DirectCast(obj, Item).Id
    End Function

    Public Overrides Function GetHashCode() As Integer
        Return Id.GetHashCode()
    End Function
End Class
现在,您可以使用高效且清晰的:

Dim list3 = list1.Union(list2).ToList
:

此方法从返回集中排除重复项。这是不同的
Concat
方法的行为,该方法返回所有 输入序列中的元素,包括重复项。。。比照 作为自定义数据类型,您需要实现此接口并提供 您自己的GetHashCode等于该类型的方法


通过在Tim Schmelter answer中添加Equals和GetHashCode,您现在还可以直接在查询中使用Concat和.Distinct:

Dim list3 As List(Of Item) = list1.Concat(list2).Distinct.ToList
或者在查询中使用where和distinct:

Dim list3 As List(Of Item) = (From data In list1.Concat(list2) Where data.Value = "MyCity" Distinct).ToList
变化:

  Dim list3 As List(Of Item) = (From data In list1.Concat(list2) Where data.Value = "MyCity").Distinct.ToList

对于那些想知道为什么GetHashCode:Stefan也是对的人来说。Concat Distinct是Union的替代品。@forX:
GetHashCode
类似于
Equals
的预过滤器。使用哈希代码查找对象的每个哈希表(例如
字典
哈希集
)将首先使用
获取哈希代码
,然后确认与
相等
<代码>GetHashCode
必须有效。对于两个不同的对象,
GetHashCode
可能返回相同的数字,但每个相等的对象必须具有相同的hashcode。这些规则和指南非常有用: