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# Equals、GetHashCode和运算符重写在IEquatable实现中未调用的内容_C#_Linq_Equals_Iequalitycomparer_Iequatable - Fatal编程技术网

C# Equals、GetHashCode和运算符重写在IEquatable实现中未调用的内容

C# Equals、GetHashCode和运算符重写在IEquatable实现中未调用的内容,c#,linq,equals,iequalitycomparer,iequatable,C#,Linq,Equals,Iequalitycomparer,Iequatable,我正在尝试实现IEqueatable,以便可以使用。自定义类型LINQ查询除外 自定义类型代码如下所示: public class Case : IEquatable<Case> { [Key] public int Id { get; set; } //More properties [...] public bool Equals(Case other) {

我正在尝试实现IEqueatable,以便可以使用。自定义类型LINQ查询除外

自定义类型代码如下所示:

public class Case : IEquatable<Case>
    {
        [Key]
        public int Id { get; set; }

        //More properties
        [...]      

        public bool Equals(Case other)
        {
            // Check whether the compared object references the same data.
            if (ReferenceEquals(this, other)) return true;

            // Check whether the compared object is null.
            if (ReferenceEquals(other, null)) return false;

            // Check whether the objects’ properties are equal.
            return Id.Equals(other.Id);
        }

        public override bool Equals(object obj)
        {
            var other = obj as Case;
            // Check whether the compared object references the same data.
            if (ReferenceEquals(this, other)) return true;

            // Check whether the compared object is null.
            if (ReferenceEquals(other, null)) return false;

            // Check whether the objects’ properties are equal.
            return Id.Equals(other.Id);
        }

        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }

        public static bool operator ==(Case case1, Case case2)
        {
            if ((object)case1 == null || (object)case2 == null)
                return Equals(case1, case2);
            return case1.Equals(case2);

        }

        public static bool operator !=(Case case1, Case case2)
        {
            if ((object)case1 == null || (object)case2 == null)
                return !Equals(case1, case2);
            return !case1.Equals(case2);
        }
    }

powerset和subset都是Case数组。

在尝试使用linq查询之前,我建议使用更简单的方法。即

var case1_1 = new Case() { Id = 1 };
var case1_2 = new Case() { Id = 1 };

var areEqual = case1_1 == case1_2;
有了这个测试,我可以想到为什么你没有遇到这个异常:

您有2个Equals方法,并且只从其中1个抛出了异常。 您所比较的两个对象没有相同的Id。如果GetHashCode的结果不同,它甚至可能不会尝试比较这些值。 异常被捕获
我很想知道你是否尝试过在两个重载中陷进相等的内容。。。从代码中弹出的唯一一件事是,您有用于检查相等性的重复实现。理想情况下,你只能在一个地方这样做

下面是一个示例实现。。。您将用Case替换EntityBase


如果您只打电话,除了:

var exceptList = list1.Except(list2);
不返回任何列表,要执行比较,您需要枚举Except的结果,例如使用foreach:

foreach(var listElement in exceptList) 
{
    //...
}
然后调用GetHashCode和Equals方法

编辑: 除以下两个列表外,此代码不执行其他操作:

    static void Main(string[] args)
    {
        List<MyClass> list1 = new List<MyClass>();

        MyClass myClass1 = new MyClass() {Id = 1};
        MyClass myClass2 = new MyClass() {Id = 2};

        list1.Add(myClass1);
        list1.Add(myClass2);

        List<MyClass> list2 = new List<MyClass>();
        list2.Add(myClass1);

        var exceptList = list1.Except(list2);

        foreach (var myClass in exceptList)
        {
            Console.WriteLine(myClass.Id);
        }
    }


    public class MyClass : IEquatable<MyClass>
    {
        public int Id { get; set; }

        public bool Equals(MyClass other)
        {
            return Id == other.Id;
        }

        public override int GetHashCode()
        {
            return Id;
        }
    }
此代码在控制台中打印2,只有在必要时才调用Equals。所有处理IEquatable实现的LINQ方法首先使用并存储它们处理的对象的哈希代码。只有当两个对象具有相同的哈希代码时,这些方法才会调用Equals

在您的数据中,没有相同ID的情况,因此永远不需要调用Equals

这很容易通过一个例子来说明。如果您有三个列表:

var list1 = new List<Case>
{
    new Case{ Id = 1 },
    new Case{ Id = 2 },
    new Case{ Id = 3 }
};
var list2 = new List<Case>
{
    new Case{ Id = 4 },
    new Case{ Id = 5 },
    new Case{ Id = 6 }
};
var list3 = new List<Case>
{
    new Case{ Id = 1 },
    new Case{ Id = 5 },
    new Case{ Id = 6 }
};
。。。将输出:

GetHashCode: 4
GetHashCode: 5
GetHashCode: 6
GetHashCode: 1
GetHashCode: 2
GetHashCode: 3
GetHashCode: 1
GetHashCode: 5
GetHashCode: 6
GetHashCode: 1
Equals: 1 - 1
GetHashCode: 2
GetHashCode: 3
虽然声明

list1.Except(list3).ToList();
。。。将输出:

GetHashCode: 4
GetHashCode: 5
GetHashCode: 6
GetHashCode: 1
GetHashCode: 2
GetHashCode: 3
GetHashCode: 1
GetHashCode: 5
GetHashCode: 6
GetHashCode: 1
Equals: 1 - 1
GetHashCode: 2
GetHashCode: 3

你能在需要调用Equals的地方添加Linq代码吗?你的测试用例有两个Id相同的用例吗?@RubenAguilar添加了代码@PetSerAl否,案例将只有一个唯一Id。使用惰性评估除外。您是否列举了newset?您好,发生的情况是,exceptList根本不起作用,因此在本例中exceptList的值将与list1相同。感谢您发布此消息,但我已经尝试过这种方式,但行为仍然相同。我知道子集中的对象在旧列表中,因为它是旧列表对象之一的powerset。电源集是一个集合,包含集合中所有可能的项目组合。因此,旧集是X项的前一个功率集,而新集是旧集的一个功率集,这意味着所有这些项都在旧列表中,因此,在我的BL中,它们需要删除。嗨,谢谢你的回答。我做了多个测试和测试:1。首先,拥有2个equals方法是实现IEqueatble的方式,一个覆盖类的前一个签名,另一个使用类型Case指定自定义比较。这在我作为参考提供的MSDN链接中有建议。永远不会抛出异常。2.我还在GetHashCode中添加了throw新异常,该异常未被计算。我知道事实上我正在比较的案例是匹配的。3.没有发现异常。@RainierMallol我并不是说你不应该有2个equals方法。我只是说您可能签入了错误的方法。谢谢,但是GetHashCode方法也从来没有被调用过。在我的例子中是这样的。您应该提供更多关于测试用例中数据的详细信息,以及如何确定未调用GetHashCode。嗨,Peter John,谢谢您的消息。您的代码缺少IQuetable.EqualEntityBase的实现。我已经将它添加到我的代码中,但仍然得到相同的结果。
GetHashCode: 1
GetHashCode: 5
GetHashCode: 6
GetHashCode: 1
Equals: 1 - 1
GetHashCode: 2
GetHashCode: 3