Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/77.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# 试图实现一个可以比较任意两个列表的方法,但它总是返回false_C#_List_Comparison_Ienumerable - Fatal编程技术网

C# 试图实现一个可以比较任意两个列表的方法,但它总是返回false

C# 试图实现一个可以比较任意两个列表的方法,但它总是返回false,c#,list,comparison,ienumerable,C#,List,Comparison,Ienumerable,我正在尝试制作一种方法,可以比较任意两个列表是否相等。我试图以一种方式比较它们,验证一个列表中的每个元素与另一个列表中的每个元素具有相同的值。下面我的Equals方法总是返回false,有人知道这是为什么吗 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; public class IEnumerableCompa

我正在尝试制作一种方法,可以比较任意两个列表是否相等。我试图以一种方式比较它们,验证一个列表中的每个元素与另一个列表中的每个元素具有相同的值。下面我的
Equals
方法总是返回
false
,有人知道这是为什么吗

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public class IEnumerableComparer<T> : IEqualityComparer<IEnumerable<T>>
{
    public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
    {
        for(int i = 0; i<x.Count();i++){
          if(!Object.Equals(x.ElementAt(i), y.ElementAt(i))){
             return false;
          }
        }
        return true;
    }

    public int GetHashCode(IEnumerable<T> obj)
    {
        if (obj == null)
            return 0;

        return unchecked(obj
            .Select(e => e.GetHashCode())
            .Aggregate(0, (a, b) => a + b)); 
    }
}
车辆等级:

   class Car
    {
        public String make { get; set; }
        public String model { get; set; }
    }
的默认版本比较引用(对于引用类型)。您的问题有三种可能的解决方案:

  • 汽车
    类覆盖
    等于
    GetHashCode

  • 添加另一个版本的
    IEnumerableComparer
    constructor,该版本将用于比较各个实例,并为每个用例提供其实现

  • 仅使用值类型,因为对于它们,的默认版本将按您预期的方式运行。请注意,这些值类型的所有字段和属性都必须符合此处给出的第一个或第三个选项(即,
    Equals
    GetHashCode
    被覆盖,或者也是值类型)。一般来说,这并不是一个推荐的解决方案,我只是把它作为一种理论上的可能性提出来。不过,在您的情况下,它会有所帮助-尝试将
    class Car
    更改为
    struct Car


此外,正如wageoghe’s正确指出的那样,您可以使用该方法而不是编写自己的实现,但您仍然需要遵守上面给出的解决方案之一(将此重载用于第二个选项)。

也许我遗漏了一些东西,但为什么不使用SequenceEqual呢


请注意,序列中的对象仍然必须正确实现Equals和GetHashCode

同时为您的汽车提供覆盖:

class Car
{
    public String make { get; set; }
    public String model { get; set; }
    public override bool Equals(object obj)
    {
        var other = obj as Car;
        return (other != null) 
                && (this.make == other.make) 
                && (this.model == other.model); 
    }
    public override int GetHashCode()
    {
        return make.GetHashCode() ^ model.GetHashCode();
    }
}

@TylerPfaff无法检查任何两个对象是否相等。如何检查
WinForms.Button
FileStream
的实例是否相等?你需要定义平等对你意味着什么。财产平等?领域平等?递归对象呢?自行车?字符串是否区分大小写?GetHashCode不需要未检查和聚合。只要obj.GetHashCode()就足够了。@usr我明白了,很抱歉我读到了你的评论,因为你试图将
Button
FileStream
类型的对象相互比较。@usr:,对于大多数对象来说,对于大多数特定的等价定义,毫不含糊地回答这个问题是没有问题的。即使是一个对象X,它不认为它本身等同于宇宙中的任何其他对象,也不应该回答<代码> x.Error(y)< /C>:它应该返回true,当且仅当引用<代码> y>代码>标识它时。
Equals
中唯一的含糊不清之处在于等价的正确含义。@supercat您可以设计一个适用于任何类型的等价:只需委托给object.ReferenceEquals即可。这总是有效的,但并不总是有用的。即使是像string这样的基本类型,框架中也至少内置了6个不同的比较器。“正确的”是什么?取决于用例。你不能构建一个比较器,它可以用于任何两个对象,并且总是同时有用。这基本上就是OP已经具备的功能
SequenceEquals
调用
Object.Equals
在封面下。他仍然会遭受引用不平等的痛苦。他对SequenceEquals的实现相当糟糕。为什么要重新实施它?如果他想重新实现,不要使用Count()和ElementAt(x)(两次)。
Bool b = l1.SequenceEqual(l2);
class Car
{
    public String make { get; set; }
    public String model { get; set; }
    public override bool Equals(object obj)
    {
        var other = obj as Car;
        return (other != null) 
                && (this.make == other.make) 
                && (this.model == other.model); 
    }
    public override int GetHashCode()
    {
        return make.GetHashCode() ^ model.GetHashCode();
    }
}