2011-07-02 119 views
7

假設被引用List下面包含2個元素:在LINQ DISTINCT與匿名類型(在VB.NET)

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 
+0

事實證明,這是一個有趣的問題Chocol8。 – Khepri

回答

32

我只能假設你已經死了使用匿名類型,因爲Alex Peck給出的答案是正確的。 (我已經提高了)。

但是,這歸結爲一個VB.NET與C#編譯器的討論。

在VB.NET中,當遇到匿名類型時,只有那些聲明爲關鍵屬性的屬性可以用於比較目的。所以在沒有鍵的VB.NET中,當你試圖做一個明確的比較時,什麼都不會發生。

Read all about it here.

因此,首先要回答你的問題,這個工作匿名類型:

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

enter image description here

這就是爲什麼freedompeace的回答完全不是那麼回事。

C#但編譯器有點不同。

當遇到匿名類型並且需要比較操作時,C#編譯器將覆蓋Equals和GetHashCode。它將遍歷匿名類型的所有公共屬性以計算對象的哈希代碼以測試相等性。

And you can read more about that here.

希望這回答了你的問題。

+0

+1有趣,我更熟悉C#,並沒有意識到這裏的區別。 –

+0

@Khepri那太棒了!謝謝! – OrElse

+0

來自[MSDN文章]的重要注意事項(http://msdn.microsoft.com/zh-cn/library/bb384767.aspx): >由查詢創建的匿名類型中的屬性始終是關鍵屬性。 另請參閱[本測試用例](https://gist.github.com/janv8000/9407469)。 – janv8000

2

還有就是LINQ操作命名鮮明的(),您可以調用像這樣:

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

更多鮮明here

+0

lonita:這不起作用 – OrElse

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

這不起作用 – OrElse

5
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 
+0

Peck這不起作用。 – OrElse

2

獨特的必須知道某種方式哪些對象是相同的。你在這裏選擇anonymus對象,它不知道哪一個是平等的。我從來沒有寫過一行VB。淨,但我想的東西,和它的作品:

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