我玩LINQ来了解它,但我不知道如何使用鲜明当我没有一个简单的列表(一个简单的整数列表是很容易做到的,这不是问题)。如果我想使用鲜明的列表<TElement>上的一个或多个属性的TElement?

示例:如果一个对象是Person,具有属性Id。我怎么能得到所有人,并使用鲜明对他们与对象的属性Id ?

Person1: Id=1, Name="Test1"
Person2: Id=1, Name="Test1"
Person3: Id=2, Name="Test2"

如何得到Person1和Person3?这可能吗?

如果用LINQ是不可能的,那么根据Person的某些属性获得Person列表的最佳方法是什么?


当前回答

List<Person>lst=new List<Person>
        var result1 = lst.OrderByDescending(a => a.ID).Select(a =>new Player {ID=a.ID,Name=a.Name} ).Distinct();

其他回答

重写Equals(object obj)和GetHashCode()方法:

class Person
{
    public int Id { get; set; }
    public int Name { get; set; }

    public override bool Equals(object obj)
    {
        return ((Person)obj).Id == Id;
        // or: 
        // var o = (Person)obj;
        // return o.Id == Id && o.Name == Name;
    }
    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }
}

然后调用:

List<Person> distinctList = new[] { person1, person2, person3 }.Distinct().ToList();

我认为这就足够了:

list.Select(s => s.MyField).Distinct();

我个人使用以下类:

public class LambdaEqualityComparer<TSource, TDest> : 
    IEqualityComparer<TSource>
{
    private Func<TSource, TDest> _selector;

    public LambdaEqualityComparer(Func<TSource, TDest> selector)
    {
        _selector = selector;
    }

    public bool Equals(TSource obj, TSource other)
    {
        return _selector(obj).Equals(_selector(other));
    }

    public int GetHashCode(TSource obj)
    {
        return _selector(obj).GetHashCode();
    }
}

然后,一个扩展方法:

public static IEnumerable<TSource> Distinct<TSource, TCompare>(
    this IEnumerable<TSource> source, Func<TSource, TCompare> selector)
{
    return source.Distinct(new LambdaEqualityComparer<TSource, TCompare>(selector));
}

最后,预期用途:

var dates = new List<DateTime>() { /* ... */ }
var distinctYears = dates.Distinct(date => date.Year);

我发现使用这种方法的优点是可以为其他接受IEqualityComparer的方法重用LambdaEqualityComparer类。(哦,我把yield的东西留给最初的LINQ实现…)

如果您需要在多个属性上使用Distinct方法,您可以查看我的PowerfulExtensions库。目前它在一个非常年轻的阶段,但你已经可以使用方法,如明确,联合,相交,除任何数量的属性;

下面是它的用法:

using PowerfulExtensions.Linq;
...
var distinct = myArray.Distinct(x => x.A, x => x.B);

如果我想根据一个或多个属性获得一个不同的列表,该怎么办?

简单!你想把他们分组,然后从中选出一个优胜者。

List<Person> distinctPeople = allPeople
  .GroupBy(p => p.PersonId)
  .Select(g => g.First())
  .ToList();

如果你想在多个属性上定义组,如下所示:

List<Person> distinctPeople = allPeople
  .GroupBy(p => new {p.PersonId, p.FavoriteColor} )
  .Select(g => g.First())
  .ToList();

注意:某些查询提供程序无法解决每个组必须至少有一个元素,在这种情况下调用First是合适的方法。如果您发现自己正在使用这样的查询提供程序,那么FirstOrDefault可以帮助您通过查询提供程序获取查询。

注2:对于EF Core(在EF Core 6之前)兼容的方法,请考虑这个答案。https://stackoverflow.com/a/66529949/8155