Enumerable.Distinct 方法 
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
返回序列中的非重复元素。
重载
| Distinct<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>) | 
						 通过使用指定的 IEqualityComparer<T> 对值进行比较,返回序列中的非重复元素。  | 
        	
| Distinct<TSource>(IEnumerable<TSource>) | 
						 通过使用默认的相等比较器对值进行比较,返回序列中的非重复元素。  | 
        	
注解
结果序列是无序的。
Distinct<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)
- Source:
 - Distinct.cs
 
- Source:
 - Distinct.cs
 
- Source:
 - Distinct.cs
 
通过使用指定的 IEqualityComparer<T> 对值进行比较,返回序列中的非重复元素。
public:
generic <typename TSource>
[System::Runtime::CompilerServices::Extension]
 static System::Collections::Generic::IEnumerable<TSource> ^ Distinct(System::Collections::Generic::IEnumerable<TSource> ^ source, System::Collections::Generic::IEqualityComparer<TSource> ^ comparer);
	public static System.Collections.Generic.IEnumerable<TSource> Distinct<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, System.Collections.Generic.IEqualityComparer<TSource> comparer);
	public static System.Collections.Generic.IEnumerable<TSource> Distinct<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, System.Collections.Generic.IEqualityComparer<TSource>? comparer);
	static member Distinct : seq<'Source> * System.Collections.Generic.IEqualityComparer<'Source> -> seq<'Source>
	<Extension()>
Public Function Distinct(Of TSource) (source As IEnumerable(Of TSource), comparer As IEqualityComparer(Of TSource)) As IEnumerable(Of TSource)
    类型参数
- TSource
 
              source 的元素类型。
参数
- source
 - IEnumerable<TSource>
 
要从中移除重复元素的序列。
- comparer
 - IEqualityComparer<TSource>
 
用于比较值的 IEqualityComparer<T>。
返回
一个包含源序列中的非重复元素的 IEnumerable<T>。
例外
              source 为 null。
示例
以下示例演示如何实现可在 方法中使用的 Distinct 相等比较器。
public class Product
{
    public string Name { get; set; }
    public int Code { get; set; }
}
// Custom comparer for the Product class
class ProductComparer : IEqualityComparer<Product>
{
    // Products are equal if their names and product numbers are equal.
    public bool Equals(Product x, Product y)
    {
        //Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;
        //Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;
        //Check whether the products' properties are equal.
        return x.Code == y.Code && x.Name == y.Name;
    }
    // If Equals() returns true for a pair of objects
    // then GetHashCode() must return the same value for these objects.
    public int GetHashCode(Product product)
    {
        //Check whether the object is null
        if (Object.ReferenceEquals(product, null)) return 0;
        //Get hash code for the Name field if it is not null.
        int hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();
        //Get hash code for the Code field.
        int hashProductCode = product.Code.GetHashCode();
        //Calculate the hash code for the product.
        return hashProductName ^ hashProductCode;
    }
}
Public Class Product
    Public Property Name As String
    Public Property Code As Integer
End Class
' Custom comparer for the Product class
Public Class ProductComparer
    Implements IEqualityComparer(Of Product)
    Public Function Equals1(
        ByVal x As Product, 
        ByVal y As Product
        ) As Boolean Implements IEqualityComparer(Of Product).Equals
        ' Check whether the compared objects reference the same data.
        If x Is y Then Return True
        'Check whether any of the compared objects is null.
        If x Is Nothing OrElse y Is Nothing Then Return False
        ' Check whether the products' properties are equal.
        Return (x.Code = y.Code) AndAlso (x.Name = y.Name)
    End Function
    Public Function GetHashCode1(
        ByVal product As Product
        ) As Integer Implements IEqualityComparer(Of Product).GetHashCode
        ' Check whether the object is null.
        If product Is Nothing Then Return 0
        ' Get hash code for the Name field if it is not null.
        Dim hashProductName = 
            If(product.Name Is Nothing, 0, product.Name.GetHashCode())
        ' Get hash code for the Code field.
        Dim hashProductCode = product.Code.GetHashCode()
        ' Calculate the hash code for the product.
        Return hashProductName Xor hashProductCode
    End Function
End Class
实现此比较器后,可以在 方法中使用Distinct对象的序列Product,如以下示例所示:
Product[] products = { new Product { Name = "apple", Code = 9 },
                       new Product { Name = "orange", Code = 4 },
                       new Product { Name = "apple", Code = 9 },
                       new Product { Name = "lemon", Code = 12 } };
// Exclude duplicates.
IEnumerable<Product> noduplicates =
    products.Distinct(new ProductComparer());
foreach (var product in noduplicates)
    Console.WriteLine(product.Name + " " + product.Code);
/*
    This code produces the following output:
    apple 9
    orange 4
    lemon 12
*/
Dim products() As Product = 
    {New Product With {.Name = "apple", .Code = 9}, 
     New Product With {.Name = "orange", .Code = 4}, 
     New Product With {.Name = "apple", .Code = 9}, 
     New Product With {.Name = "lemon", .Code = 12}}
' Exclude duplicates.
Dim noduplicates = products.Distinct(New ProductComparer())
For Each product In noduplicates
    Console.WriteLine(product.Name & " " & product.Code)
Next
' This code produces the following output:
'
' apple 9
' orange 4
' lemon 12
'
    	注解
此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 在通过直接调用GetEnumerator其方法或通过在 C# For Each 或 foreach Visual Basic 中使用 来枚举对象之前,不会执行此方法表示的查询。
方法 Distinct<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>) 返回不包含重复值的无序序列。 如果 comparer 为 null,则使用默认相等比较器 Default来比较值。
适用于
Distinct<TSource>(IEnumerable<TSource>)
- Source:
 - Distinct.cs
 
- Source:
 - Distinct.cs
 
- Source:
 - Distinct.cs
 
通过使用默认的相等比较器对值进行比较,返回序列中的非重复元素。
public:
generic <typename TSource>
[System::Runtime::CompilerServices::Extension]
 static System::Collections::Generic::IEnumerable<TSource> ^ Distinct(System::Collections::Generic::IEnumerable<TSource> ^ source);
	public static System.Collections.Generic.IEnumerable<TSource> Distinct<TSource> (this System.Collections.Generic.IEnumerable<TSource> source);
	static member Distinct : seq<'Source> -> seq<'Source>
	<Extension()>
Public Function Distinct(Of TSource) (source As IEnumerable(Of TSource)) As IEnumerable(Of TSource)
    类型参数
- TSource
 
              source 的元素类型。
参数
- source
 - IEnumerable<TSource>
 
要从中移除重复元素的序列。
返回
一个包含源序列中的非重复元素的 IEnumerable<T>。
例外
              source 为 null。
示例
下面的代码示例演示如何使用 Distinct<TSource>(IEnumerable<TSource>) 从整数序列返回不同的元素。
List<int> ages = new List<int> { 21, 46, 46, 55, 17, 21, 55, 55 };
IEnumerable<int> distinctAges = ages.Distinct();
Console.WriteLine("Distinct ages:");
foreach (int age in distinctAges)
{
    Console.WriteLine(age);
}
/*
 This code produces the following output:
 Distinct ages:
 21
 46
 55
 17
*/
' Create a list of integers.
Dim ages As New List(Of Integer)(New Integer() _
                             {21, 46, 46, 55, 17, 21, 55, 55})
' Select the unique numbers in the List.
Dim distinctAges As IEnumerable(Of Integer) = ages.Distinct()
Dim output As New System.Text.StringBuilder("Distinct ages:" & vbCrLf)
For Each age As Integer In distinctAges
    output.AppendLine(age)
Next
' Display the output.
Console.WriteLine(output.ToString)
' This code produces the following output:
'
' Distinct ages:
' 21
' 46
' 55
' 17
如果要从某些自定义数据类型的对象序列中返回不同的元素,则必须在 类中实现 IEquatable<T> 泛型接口。 下面的代码示例演示如何在自定义数据类型中实现此接口,并提供 GetHashCode 和 Equals 方法。
public class MyProduct : IEquatable<MyProduct>
{
    public string Name { get; set; }
    public int Code { get; set; }
    public bool Equals(MyProduct other)
    {
        //Check whether the compared object is null.
        if (Object.ReferenceEquals(other, null)) return false;
        //Check whether the compared object references the same data.
        if (Object.ReferenceEquals(this, other)) return true;
        //Check whether the products' properties are equal.
        return Code.Equals(other.Code) && Name.Equals(other.Name);
    }
    // If Equals() returns true for a pair of objects
    // then GetHashCode() must return the same value for these objects.
    public override int GetHashCode()
    {
        //Get hash code for the Name field if it is not null.
        int hashProductName = Name == null ? 0 : Name.GetHashCode();
        //Get hash code for the Code field.
        int hashProductCode = Code.GetHashCode();
        //Calculate the hash code for the product.
        return hashProductName ^ hashProductCode;
    }
}
Public Class Product
    Implements IEquatable(Of Product)
    Public Property Name As String
    Public Property Code As Integer
    Public Function Equals1(
        ByVal other As Product
        ) As Boolean Implements IEquatable(Of Product).Equals
        ' Check whether the compared object is null.
        If other Is Nothing Then Return False
        ' Check whether the compared object references the same data.
        If Me Is Other Then Return True
        ' Check whether the products' properties are equal.
        Return Code.Equals(other.Code) AndAlso Name.Equals(other.Name)
    End Function
    Public Overrides Function GetHashCode() As Integer
        ' Get hash code for the Name field if it is not null.
        Dim hashProductName = If(Name Is Nothing, 0, Name.GetHashCode())
        ' Get hash code for the Code field.
        Dim hashProductCode = Code.GetHashCode()
        ' Calculate the hash code for the product.
        Return hashProductName Xor hashProductCode
    End Function
End Class
实现此接口后,可以在 方法中使用Distinct<TSource>(IEnumerable<TSource>)对象的序列Product,如以下示例所示:
MyProduct[] products = { new MyProduct { Name = "apple", Code = 9 },
                       new MyProduct { Name = "orange", Code = 4 },
                       new MyProduct { Name = "apple", Code = 9 },
                       new MyProduct { Name = "lemon", Code = 12 } };
// Exclude duplicates.
IEnumerable<MyProduct> noduplicates =
    products.Distinct();
foreach (var product in noduplicates)
    Console.WriteLine(product.Name + " " + product.Code);
/*
    This code produces the following output:
    apple 9
    orange 4
    lemon 12
*/
Dim products() As Product = 
    {New Product With {.Name = "apple", .Code = 9}, 
     New Product With {.Name = "orange", .Code = 4}, 
     New Product With {.Name = "apple", .Code = 9}, 
     New Product With {.Name = "lemon", .Code = 12}}
' Exclude duplicates.
Dim noduplicates = products.Distinct()
For Each product In noduplicates
    Console.WriteLine(product.Name & " " & product.Code)
Next
' This code produces the following output:
'
' apple 9
' orange 4
' lemon 12
'
    	注解
此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 在通过直接调用GetEnumerator其方法或通过在 C# For Each 或 foreach Visual Basic 中使用 来枚举对象之前,不会执行此方法表示的查询。
方法 Distinct<TSource>(IEnumerable<TSource>) 返回不包含重复值的无序序列。 它使用默认相等比较器 Default来比较值。
在 Visual Basic 查询表达式语法中, Distinct 子句转换为 的 Distinct调用。
默认相等比较器 Default用于比较实现 IEquatable<T> 泛型接口的类型的值。 若要比较自定义数据类型,需要实现此接口并为该类型提供自己的 GetHashCode 和 Equals 方法。
有关使用 IEqualityComparer<T> 定义自定义比较器的示例,请参阅 Distinct<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)。