LINQ 中与匿名类型不同(在 VB.NET 中)

发布于 2024-11-18 15:59:50 字数 390 浏览 3 评论 0原文

假设下面引用的 List 包含 2 个元素:

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

上面的代码返回

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

如何获取不同的值? Countries 查询应仅包含

.Country=Spain .CountryID = 1

Supposing the referenced List below contains 2 elements:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

忆依然 2024-11-25 15:59:50

我只能假设您坚决使用匿名类型,因为 Alex Peck 给出的答案是正确的。 (我已经投了赞成票)。

然而,这归结为 VB.NET 与 C# 编译器的讨论。

在 VB.NET 中,当遇到匿名类型时,只有那些声明为关键属性的属性可用于比较目的。因此,在没有键的 VB.NET 中,当您尝试进行不同比较时,不会发生任何事情。

在此处阅读所有相关内容。

首先,回答您的问题,这适用于匿名类型:

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

在此处输入图像描述

这就是 Freedompeace 的答案不太有效的原因。

然而 C# 的编译器有点不同。

当遇到匿名类型并且需要比较操作时,C# 编译器会重写 Equals 和 GetHashCode。它将迭代匿名类型的所有公共属性来计算对象的哈希码以测试相等性。

您可以阅读更多内容关于这一点,请点击此处。

希望这能回答您的问题。

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

enter image description here

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.

岁吢 2024-11-25 15:59:50
Dim distinctCountries = Countries.Distinct()

当我停在调试器的最后一行时,这对我有用:

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
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
时光沙漏 2024-11-25 15:59:50

Distinct 必须以某种方式知道哪些对象是相同的。你在这里选择匿名对象,它不知道哪些是相等的。我从来没有写过一行 VB.Net,但我尝试了一些东西,它起作用了:

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

在你的情况下:

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

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
和我恋爱吧 2024-11-25 15:59:50

有一个名为 Distinct() 的 LINQ 运算符,您可以像这样调用它:

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

有关 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

醉生梦死 2024-11-25 15:59:50
Dim Countries = From c In List _
                 Select New With {.Country = c.Country, .CountryID = c.CountryID }.Distinct() 
Dim Countries = From c In List _
                 Select New With {.Country = c.Country, .CountryID = c.CountryID }.Distinct() 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文