Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过列表属性比较相等性_C#_Linq_List - Fatal编程技术网

C# 通过列表属性比较相等性

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

我试图找到列表中的项目数,这些项目在一个属性中不同,而属性本身就是一个列表。我使用Linq找到了这个示例:

如果取而代之的是,我在
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();