当前位置: 首页 > article >正文

C#常考随笔3:对象比较obj1.Equals(obj2)== true时候,hashcode是否相同?

一般情况下是相同的,但在自定义类型中,重写了Equals方法,就可能不同。

Equals:

1. 首先,关于Equals方法:

Equals 方法最初定义在 Object 类中,所有的类都直接或间接地继承自 Object 类,因此所有对象都可以调用该方法。Object 类中的 Equals 方法默认比较的是对象的引用是否相等,即判断两个变量是否指向内存中的同一个对象实例。

示例代码

using System;

class Program
{
    static void Main()
    {
        object obj1 = new object();
        object obj2 = obj1;
        object obj3 = new object();

        Console.WriteLine(obj1.Equals(obj2)); // 输出: True,因为 obj1 和 obj2 引用同一个对象
        Console.WriteLine(obj1.Equals(obj3)); // 输出: False,因为 obj1 和 obj3 引用不同的对象
    }
}

2. 重写 Equals 方法

许多类会重写 Equals 方法,以便根据对象的内容来判断它们是否相等,而不仅仅是比较引用。例如,string 类就重写了 Equals 方法,用于比较两个字符串的内容是否相同。

示例代码

using System;

class Program
{
    static void Main()
    {
        string str1 = "hello";
        string str2 = "hello";

        Console.WriteLine(str1.Equals(str2)); // 输出: True,因为 str1 和 str2 的内容相同
    }
}

3. 自定义类重写 Equals 方法

当创建自定义类时,如果需要根据对象的属性来判断对象是否相等,就需要重写 Equals 方法。同时,为了遵循最佳实践,还应该重写 GetHashCode 方法,因为相等的对象应该具有相同的哈希码。

示例代码

using System;

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
            return false;

        Person other = (Person)obj;
        return Name == other.Name && Age == other.Age;
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(Name, Age);
    }
}

class Program
{
    static void Main()
    {
        Person person1 = new Person { Name = "Alice", Age = 25 };
        Person person2 = new Person { Name = "Alice", Age = 25 };

        Console.WriteLine(person1.Equals(person2)); // 输出: True,因为两个对象的属性值相同
    }
}

 什么时候hascode同,什么时候不同

以下是一个符合正常规则的示例:

using System;

class Program
{
    static void Main()
    {
        string x = "hello";
        string y = "hello";

        bool areEqual = x.Equals(y);
        int hashCodeX = x.GetHashCode();
        int hashCodeY = y.GetHashCode();

        Console.WriteLine($"Are equal: {areEqual}");
        Console.WriteLine($"Hash code of x: {hashCodeX}");
        Console.WriteLine($"Hash code of y: {hashCodeY}");
        Console.WriteLine($"Hash codes are equal: {hashCodeX == hashCodeY}");
    }
}

在上述代码中,x 和 y 是两个值相同的字符串对象,它们通过 Equals 方法比较返回 true,并且它们的哈希码也是相同的。

特殊情况

如果在自定义类型中,手动重写了 Equals 方法和 GetHashCode 方法,并且没有遵循 “相等对象具有相同哈希码” 的原则,就可以让两个通过 Equals 方法比较相等的对象具有不同的哈希码。但这种做法是不推荐的,因为它会破坏很多基于哈希码的集合类的正常工作。

以下是一个错误示范的示例:

using System;

class MyClass
{
    public int Value { get; set; }

    public MyClass(int value)
    {
        Value = value;
    }

    public override bool Equals(object obj)
    {
        if (obj is MyClass other)
        {
            return this.Value == other.Value;
        }
        return false;
    }

    public override int GetHashCode()
    {
        // 故意返回不同的哈希码
        return new Random().Next();
    }
}

class Program
{
    static void Main()
    {
        MyClass x = new MyClass(10);
        MyClass y = new MyClass(10);

        bool areEqual = x.Equals(y);
        int hashCodeX = x.GetHashCode();
        int hashCodeY = y.GetHashCode();

        Console.WriteLine($"Are equal: {areEqual}");
        Console.WriteLine($"Hash code of x: {hashCodeX}");
        Console.WriteLine($"Hash code of y: {hashCodeY}");
        Console.WriteLine($"Hash codes are equal: {hashCodeX == hashCodeY}");
    }
}

在这个示例中,MyClass 类重写了 Equals 方法和 GetHashCode 方法,Equals 方法根据 Value 属性判断两个对象是否相等,但 GetHashCode 方法返回一个随机数,这就导致两个相等的对象可能具有不同的哈希码。需要修改:

public override int GetHashCode()
{
    return HashCode.Combine(Value);
}

http://www.kler.cn/a/520244.html

相关文章:

  • MATLAB绘图:随机彩色圆点图
  • js手撕 | 使用css画一个三角形 使用js修改元素样式 驼峰格式与“-”格式相互转化
  • 想品客老师的第七天:闭包和作用域
  • HBase-2.5.10 伪分布式环境搭建【Mac】
  • iOS 集成ffmpeg
  • 笔试-二维数组
  • Java的循环结构
  • 【数据结构】_链表经典算法OJ:合并两个有序数组
  • 随笔十七、eth0单网卡绑定双ip的问题
  • 题解 洛谷 Luogu P1113 杂务 图论 BFS C++
  • 计算机网络之链路层
  • CommonAPI学习笔记-1
  • 【Oracle篇】使用Hint对优化器的执行计划进行干预(含单表、多表、查询块、声明四大类Hint干预)
  • 牛客训练营(一)补题
  • 【2025AI发展预测】2.2025的风口与发展,我们如何主动拥抱这一浪潮
  • 可见光通信代码仿真
  • 狗狗能吃萝卜吗?
  • vim可视化模式的进阶操作
  • C# 类(Class)
  • SOME/IP--协议英文原文讲解1
  • 深度解析:基于Vue 3的教育管理系统架构设计与优化实践
  • 【论文阅读笔记】“万字”关于深度学习的图像和视频阴影检测、去除和生成的综述笔记 | 2024.9.3
  • 【趋势】《2024—2026金融科技十大趋势预测》一览
  • 【学术会议-第五届机械设计与仿真国际学术会议(MDS 2025) 】前端开发:技术与艺术的完美融合
  • Kiwi 安卓浏览器本月停止维护,扩展功能迁移至 Edge Canary
  • 基于SpringBoot的在线众筹网的设计与实现(源码+SQL脚本+LW+部署讲解等)