c# - 在 lambda 上执行 distinct() 时替换 IEquatable 接口
问题描述
我有这个实现IEquatable<T>
接口的类
public class ArticleDescriptionDetails : IEquatable<ArticleDescriptionDetails>
{
public string Code { get; set; }
public string Value { get; set; }
public bool Hidden { get; set; }
public bool Equals(ArticleDescriptionDetails other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Code == other.Code;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return obj.GetType() == GetType() && Equals((ArticleDescriptionDetails) obj);
}
public override int GetHashCode() => ((Code != null ? Code.GetHashCode() : 0) * 397) ^ Hidden.GetHashCode();
public static bool operator ==(ArticleDescriptionDetails left, ArticleDescriptionDetails right) => Equals(left, right);
public static bool operator !=(ArticleDescriptionDetails left, ArticleDescriptionDetails right) => !Equals(left, right);
}
我需要这个,因为我想以IEquatable<ArticleDescriptionDetails>
这种方式返回一个:
return result.OrderBy(x => x.Code).ThenBy(y => y.Hidden).Distinct();
有没有办法在不使用IEquatable<T>
界面的情况下做同样的事情?
解决方案
您可以使用 DistinctBy 方法并执行
return result.OrderBy(x => x.Code).ThenBy(y => y.Hidden).DistinctBy(z => z.Code);
但是 linq 中不存在 DistinctBy 方法,但您可以在 morelinq 包中找到它https://www.nuget.org/packages/MoreLinq.Source.MoreEnumerable.DistinctBy/
但是编写自己的方法版本也很容易:首先需要定义一个 IEqualityComparer
public class KeyEqualityComparer<T, K> : IEqualityComparer<T>
{
private readonly Func<T, K> selector;
public KeyEqualityComparer(Func<T, K> keySelector)
{
selector = keySelector;
}
public bool Equals(T x, T y)
{
return selector(x).Equals(selector(y));
}
public int GetHashCode(T obj)
{
return selector(obj).GetHashCode();
}
}
您可以在 Distinct 方法中使用此 IEqualityComparer :
public static IEnumerable<T> DistinctBy<T, K>(this IEnumerable<T> list, Func<T, K> keySelector)
{
var equalityComparer = new KeyEqualityComparer<T, K>(keySelector);
return list.Distinct(equalityComparer);
}
推荐阅读
- c# - Where do I find my logs in azure app services?
- redux-saga - How to test if else in redux saga
- android - androidx.constraintlayout.widget.ConstraintLayout cannot be cast to android.widget.TextView
- ios - SwiftUI Image clipsToBounds
- npm - failed to start nuxt project through pm2
- kotlin - 如何在 kotlin 中从用户那里获取 char 值?
- python - 不平衡学习的 FunctionSampler 抛出 ValueError
- reactjs - Re-request on state change react
- google-apps-script - Client Projects Google Sheet - How to update rows based on status?
- javascript - How to avoid that scrollTop function on accordion works for children?