C# 通过列表属性比较相等性
我试图找到列表中的项目数,这些项目在一个属性中不同,而属性本身就是一个列表。我使用Linq找到了这个示例: 如果取而代之的是,我在C# 通过列表属性比较相等性,c#,linq,list,C#,Linq,List,我试图找到列表中的项目数,这些项目在一个属性中不同,而属性本身就是一个列表。我使用Linq找到了这个示例: 如果取而代之的是,我在ListOfActions中选择第一项,它会工作: List<Target> distinctTargets = SelectedTargets.GroupBy(p => p.ListOfActions[0]).Select(g => g.First()).ToList(); 并且是DispensingActionList: private
ListOfActions
中选择第一项,它会工作:
List<Target> distinctTargets = SelectedTargets.GroupBy(p => p.ListOfActions[0]).Select(g => g.First()).ToList();
并且是DispensingActionList:
private DispensingActionList ListOfActions = new DispensingActionList();
public class DispensingActionList : List<DispensingAction>
{ ...
private DispensingActionList ListOfActions=new DispensingActionList();
公共类DispensingActionList:列表
{ ...
您可以使用
如果尚未覆盖类型的
GetHashCode
和Equals
方法,则必须覆盖这些方法。您可以为比较序列的GroupBy
重载使用自定义的IEqualityComparer
。例如,它使用可枚举的.SequenceEqual
:
public class SequenceComparer<T> : IEqualityComparer<IEnumerable<T>>
{
public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
{
if (x == null && y == null) return true;
if (x == null || y == null) return false;
var comparer = EqualityComparer<T>.Default;
return x.SequenceEqual(y, comparer);
}
public int GetHashCode(IEnumerable<T> items)
{
unchecked
{
int hash = 17;
foreach (T item in items)
{
hash = hash * 23 + (item == null ? 0 : item.GetHashCode());
}
return hash;
}
}
}
公共类SequenceComparer:IEqualityComparer
{
公共布尔等于(IEnumerable x,IEnumerable y)
{
如果(x==null&&y==null)返回true;
如果(x==null | | y==null)返回false;
var comparer=EqualityComparer.Default;
返回x.SequenceEqual(y,比较器);
}
public int GetHashCode(IEnumerable项)
{
未经检查
{
int hash=17;
foreach(项目中的T项目)
{
hash=hash*23+(item==null?0:item.GetHashCode());
}
返回散列;
}
}
}
现在,这应该是可行的:
List<Target> distinctTargets = SelectedTargets
.GroupBy(p => p.ListOfActions, new SequenceComparer<DispensingAction>())
.Select(g => g.First())
.ToList();
List distinctTargets=SelectedTargets
.GroupBy(p=>p.ListOfActions,new SequenceComparer())
.Select(g=>g.First())
.ToList();
当然,
DispensingAction
还需要重写Equals
来有意义地比较对象,而不仅仅是检查它们是否是相同的引用。为什么不重写ListOfActions类的Equals()方法呢?请参见,其中的共识是“不,它们不应该”!好的。我会记住的。对不起。我刚刚开始尝试这个。它工作得很好,所以谢谢!但是我更喜欢一个解决方案,在这个解决方案中,我不必实例化新对象(SequenceComparer)来测试相等性,这样Linq行将保持如下状态:List distinctTargets=SelectedTargets.GroupBy(p=>p.ListOfActions)。选择(g=>g.First()).ToList();
I重写Equals(IList obj)
并如上所述使用Linq行,但返回false
。有什么建议吗?
private DispensingActionList ListOfActions = new DispensingActionList();
public class DispensingActionList : List<DispensingAction>
{ ...
public class SequenceComparer<T> : IEqualityComparer<IEnumerable<T>>
{
public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
{
if (x == null && y == null) return true;
if (x == null || y == null) return false;
var comparer = EqualityComparer<T>.Default;
return x.SequenceEqual(y, comparer);
}
public int GetHashCode(IEnumerable<T> items)
{
unchecked
{
int hash = 17;
foreach (T item in items)
{
hash = hash * 23 + (item == null ? 0 : item.GetHashCode());
}
return hash;
}
}
}
List<Target> distinctTargets = SelectedTargets
.GroupBy(p => p.ListOfActions, new SequenceComparer<DispensingAction>())
.Select(g => g.First())
.ToList();