Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在LINQ中使用匿名类型进行区分(在VB.NET中)_.net_Vb.net_Linq_Linq To Objects_Distinct - Fatal编程技术网

在LINQ中使用匿名类型进行区分(在VB.NET中)

在LINQ中使用匿名类型进行区分(在VB.NET中),.net,vb.net,linq,linq-to-objects,distinct,.net,Vb.net,Linq,Linq To Objects,Distinct,假设下面引用的列表包含2个元素: Dim Countries = From c In List _ Select New With { .Country = c.Country, .CountryID = c.CountryID } 上面的代码返回 .Country=Spain .CountryID = 1 .Country=Spain .CountryID = 1 如何获得不同的值?“国家/地区”查询应仅包含 .Country=Spain .CountryI

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

Dim Countries = From c In List _
                Select New With { .Country = c.Country, .CountryID = c.CountryID }
上面的代码返回

.Country=Spain .CountryID = 1
.Country=Spain .CountryID = 1
如何获得不同的值?“国家/地区”查询应仅包含

.Country=Spain .CountryID = 1

有一个名为Distinct的LINQ操作符,您可以这样调用它:

 Dim Countries = (From c In List _
             Select c.Country, c.CountryID).Distinct()
有关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

我只能假设你死定了要使用匿名类型,因为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编译器将重写Equals和GetHashCode。它将迭代匿名类型的所有公共属性,以计算对象的哈希代码来测试是否相等


希望这能回答您的问题。

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

这原来是一个有趣的问题,乔科尔8。+1有趣的是,我更精通C语言,并且没有意识到这里的差异。@Khepri这太棒了!谢谢来自的重要说明:>由查询创建的匿名类型中的属性始终是键属性。另见。
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