尝试实现一个方法,可以比较任何两个列表,但它总是返回false [英] Trying to implement a method that can compare any two lists but it always returns false

查看:192
本文介绍了尝试实现一个方法,可以比较任何两个列表,但它总是返回false的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做,可以比较任意两个列表相等的方法。我想他们在这验证了一个列表中的每一个元素都有相同的值,另一个列表中的每个元素的方式进行比较。我的等于方法如下总是返回,任何人都可以看到这是为什么?



 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;使用System.Threading.Tasks
;

公共类IEnumerableComparer< T> :&的IEqualityComparer LT; IEnumerable的< T>>
{
公共布尔等于(IEnumerable的< T> X,IEnumerable的< T> Y)
{
的for(int i = 0; I< x.Count();我++ ){
如果){
返回假(的Object.Equals(x.ElementAt(ⅰ),y.ElementAt(ⅰ)!);
}
}
返回真;
}

公众诠释的GetHashCode(IEnumerable的< T> OBJ)
{
如果(OBJ == NULL)
返回0;

返回选中(OBJ
。选择(E => e.GetHashCode())
.Aggregate(0,(A,B)=> A + B) );
}
}

下面是我的数据我使用这个测试等于方法:

 静态无效的主要(字串[] args)
{
车CAR1 =新车();
car1.make =丰田;
car1.model =的xB;

车CAR2 =新车();
car2.make =丰田;
car2.model =的xB;

名单,LT;汽车> L1 =新的List<汽车>();
名单,LT;汽车> L2 =新的List<汽车>();
l1.Add(CAR1);
l2.Add(CAR2);

IEnumerableComparer<汽车> SEQ =新IEnumerableComparer<汽车>();

布尔B = seq.Equals(L1,L2);

Console.Write(二); //总是说假
Console.Read();
}
}



车类:

 类汽车
{
公共字符串化妆{搞定;组; }
公共字符串模式{搞定;组; }
}


解决方案

默认版本< A HREF =http://msdn.microsoft.com/en-us/library/bsc2ak47%28v=vs.110%29.aspx相对=nofollow> 等于 比较引用(引用类型)。有你的问题,有三种可能的解决方案:




  • 覆盖等于的GetHashCode


  • 添加T> 构造函数接受的 IEnumerableComparer及的另一个版本相对=nofollow> 的IEqualityComparer< T> 将被用于比较各个实例,并提供其为每个用例执行


  • 使用唯一的价值类型,对他们的 等于 将像你期望的那样。需要注意的是各个领域和这些价值类型的属性必须符合此处给出的第一或第三选项(即要么有等于的GetHashCode 覆盖或者是值类型也可以)。这不是真的,一般推荐的解决方案,我只是提到它作为一种理论上的可能性。你的情况,这将有助于虽然 - 尝试改变类汽车结构汽车




此外,作为正确地指出的wageoghe的答案您可以使用 SequenceEqual 方法,而不是写自己的实现,但你仍然需要遵守上面给出的解决方案之一(使用本的 SequenceEqual 过载第二个选项)


I'm trying to make a method that can compare any two lists for equality. I'm trying to compare them in a way that validates that every element of one list has the same value as every element of another list. My Equals method below always returns false, can anyone see why that is?

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)); 
    }
}

Here is my data I'm using to test this Equals method:

 static void Main(string[] args)
        {
            Car car1 = new Car();
            car1.make = "Toyota";
            car1.model = "xB";

            Car car2 = new Car();
            car2.make = "Toyota";
            car2.model = "xB";

            List<Car> l1 = new List<Car>();
            List<Car> l2 = new List<Car>();
            l1.Add(car1);
            l2.Add(car2);

           IEnumerableComparer<Car> seq = new IEnumerableComparer<Car>();

           bool b = seq.Equals(l1, l2);

           Console.Write(b); //always says false
           Console.Read();
        }
    }

Car class:

   class Car
    {
        public String make { get; set; }
        public String model { get; set; }
    }

解决方案

The default version of Equals compares references (for reference types). There are three possible solutions to your problem:

  • override Equals and GetHashCode for the Car class

  • add another version of IEnumerableComparer<T> constructor accepting IEqualityComparer<T> which will be used to compare individual instances and provide its implementation for each use case

  • use only value types, as for them the default version of Equals will behave as you expect. Note that all fields and properties of these value types will have to conform to the 1st or 3rd option given here (i.e. either have Equals and GetHashCode overridden or be a value type also). It's not really a recommended solution in general, I just mention it as a theoretical possibility. In your case it would help though - try changing class Car to struct Car.

Also, as correctly pointed out by wageoghe's answer you can use the SequenceEqual method instead of writing your own implementation, but still you need to comply to one of the solutions given above (using this SequenceEqual overload for the second option).

这篇关于尝试实现一个方法,可以比较任何两个列表,但它总是返回false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆