开发者

Distinct in LINQ with anonymous types (in VB.NET)

开发者 https://www.devze.com 2023-03-17 01:13 出处:网络
Supposing the referenced List below contains 2 elements: Dim Countries = From c In List _ Select New With { .Country = c.Country, .CountryID = c.CountryID }开发者_如何学Python

Supposing the referenced List below contains 2 elements:

Dim Countries = From c In List _
                Select New With { .Country = c.Country, .CountryID = c.CountryID }开发者_如何学Python

the code above returns

.Country=Spain .CountryID = 1
.Country=Spain .CountryID = 1

How can i get the distinct values? The Countries query should contain only

.Country=Spain .CountryID = 1


I can only assume you're dead set on the use of anonymous type as the answer given by Alex Peck is correct. (and I've upvoted it).

However, this boils down to a VB.NET vs C# compiler discussion.

In VB.NET, when an anonymous type is encountered only those properties declared as key properties can be used for comparison purposes. So in VB.NET without key, when you're attempting to do a distinct comparison, nothing will occur.

Read all about it here.

So first, to answer your question, this works with anonymous types:

Dim Countries = From c In List Select New With {Key c.CountryId, c.Country} Distinct.ToList

Distinct in LINQ with anonymous types (in VB.NET)

This is why freedompeace's answer doesn't quite work.

C# however the compiler is a little different.

When an anonymous type is encountered and a comparison operation is needed the c# compiler overrides Equals and GetHashCode. It will iterate over all of the public properties of the anonymous type to compute the object's hash code to test for equality.

And you can read more about that here.

Hope this answers your question.


Dim distinctCountries = Countries.Distinct()

This works for me when I stop on the last line in the debugger:

Imports System.Text

<TestClass()>
Public Class UnitTest1

    Class Test
        Public Country As String
        Public CountryID As Integer
    End Class

    <TestMethod()>
    Public Sub TestMethod1()

        Dim List(1) As Test
        List(0) = New Test With {.Country = "Spain", .CountryID = 1}
        List(1) = New Test With {.Country = "Spain", .CountryID = 1}

        Dim Countries = From c In List Select c.Country, c.CountryID

        Dim distinctCountries = Countries.Distinct()
    End Sub

End Class


Distinct must know somehow which objects are the same. You select anonymus objects here, it doesn't know which are equal. I never wrote a single line of VB.Net, but I tried something, and it works:

Module Module1

    Sub Main()
        Dim countries As List(Of Country) = New List(Of Country)
        Dim spain1 As Country = New Country()
        Dim spain2 As Country = New Country()
        Dim spain3 As Country = New Country()
        Dim hungary As Country = New Country()
        spain1.ID = 1
        spain1.Name = "Spain"
        spain2.ID = 1
        spain2.Name = "Spain"
        spain3.ID = 2
        spain3.Name = "Spain"
        hungary.ID = 3
        hungary.Name = "Hungary"
        countries.Add(spain1)
        countries.Add(spain2)
        countries.Add(spain3)
        countries.Add(hungary)

        Dim ctr = From c In countries Select c.Name, c.ID
                  Distinct

        For Each c In ctr
            Console.WriteLine(c)
        Next
    End Sub

    Public Class Country

        Protected _name As String

        Protected _id As Long

        Public Property Name() As String
            Get
                Return _name
            End Get
            Set(ByVal value As String)
                _name = value
            End Set
        End Property

        Public Property ID() As Long
            Get
                Return _id
            End Get
            Set(ByVal value As Long)
                _id = value
            End Set
        End Property

    End Class
End Module

In your case:

Dim Countries = From c In List 
                Select c.Country, c.CountryID Distinct


There is the LINQ operator named Distinct(), which you can call like so:

 Dim Countries = (From c In List _
             Select c.Country, c.CountryID).Distinct()

More information on Distinct here


Dim Countries = From c In List _
                 Select New With {.Country = c.Country, .CountryID = c.CountryID }.Distinct() 
0

精彩评论

暂无评论...
验证码 换一张
取 消