为什么 == 在比较使用相同 int 值装箱的两个对象类型变量时不起作用

2023-11-25

在尝试用 C# 实现一个简单的单链表时,我注意到==在比较用 int 值装箱的两个对象类型变量时不起作用,但是.Equals works.

想检查一下为什么会这样。

下面的代码片段是通用对象类型数据属性

public class Node {
    /// <summary>
    /// Data contained in the node
    /// </summary>
    private object Data { get; set; };
}

下面的代码遍历单链表并搜索对象类型的值 -

/// <summary>
/// <param name="d">Data to be searched in all the nodes of a singly linked list
/// Traverses through each node of a singly linked list and searches for an element
/// <returns>Node if the searched element exists else null </returns>
public Node Search(object d)
{
    Node temp = head;

    while (temp != null)
    {
        if (temp.Data.Equals(d))
        {
            return temp;
        }

        temp = temp.Next;
    }

    return null;
}

但是,如果我更换

temp.Data.Equals(d)

和 temp.Data == d

即使它停止工作temp.Data and d两者的值为“3”。任何原因==不适用于对象类型变量?

这是 Main 函数的片段 -

SinglyLinkedList list = new SinglyLinkedList();
list.Insert(1);
list.Insert(2);
list.Insert(3);
list.Insert(4);
list.Insert(5);

list.Print();

Node mid = list.Search(3);

我相信因为我传递了一个 int 值3并且 Search 方法需要一个对象类型,它会成功地将 3 装箱为对象类型。然而,不知道为什么==不起作用但是.Equals does.

Is ==仅对值类型重载运算符?


原因有二:

  • Equals不受限于==反之亦然,默认情况下检查引用相等性:

    正如您可以在规格中阅读的那样.Equals vs ==:

    默认情况下,运营商==通过确定两个引用是否指示同一个对象来测试引用相等性,因此引用类型不需要实现运算符==为了获得这个功能。当类型不可变时,意味着实例中包含的数据不能更改,重载运算符==比较值相等而不是引用相等可能很有用,因为作为不可变对象,只要它们具有相同的值,就可以认为它们是相同的。重写运算符==不建议在非不可变类型中使用。

    重载运算符==实现不应抛出异常。任何重载运算符的类型==还应该重载运算符!=.

    虽然如果不重写编译器会抛出错误!=也会警告你最好覆盖这两个.Equals and .GetHashCode.

    所以重写/重载.Equals, == and !=是不同的东西。压倒一切.Equals对超载没有影响== and !=。毕竟==是一个自定义运算符。尽管这样做并不明智,但您可以将其用于相等检查之外的其他目的。

  • 此外,运营商解决了编译时:

    以下面为例csharp交互式shell程序:

    $ csharp
    Mono C# Shell, type "help;" for help
    
    Enter statements below.
    csharp> public class Foo {
          >  
          > public int data;
          >  
          > public static bool operator == (Foo f1, Foo f2) {
          >     return f1.data == f2.data;
          > }
          >  
          > public static bool operator != (Foo f1, Foo f2) {
          >  
          >     return f1.data != f2.data;
          > }
          >  
          > }
    (1,15): warning CS0660: `Foo' defines operator == or operator != but does not override Object.Equals(object o)
    (1,15): warning CS0661: `Foo' defines operator == or operator != but does not override Object.GetHashCode()
    csharp> object f = new Foo();
    csharp> object f2 = new Foo();
    csharp> f == f2
    false
    csharp> Foo f3 = f as Foo;
    csharp> Foo f4 = f2 as Foo;
    csharp> f3 == f4
    true
    

    如你看到的,==如果您将对象称为object, or as Foo。由于您使用object,编译时 C# 可以进行的唯一绑定是引用相等的绑定。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 == 在比较使用相同 int 值装箱的两个对象类型变量时不起作用 的相关文章

随机推荐

  • 在项目之间共享变量

    我对一些项目有一个解决方案 其中一个项目是我定义为 main 的项目 他的类也有一个 main 方法 在这个类中 我定义了一些公共和静态属性 我想要的是从其他项目文件访问此属性 例如 项目A namespace Cobra public s
  • MediaElement 支持哪些格式?

    在 C 中 什么格式MediaElement支持 以下是支持的格式编解码器的汇总列表MediaElement 无论文件扩展名如何 都支持这些编码 Source https msdn microsoft com en us library c
  • 如何在 Spring Boot Embedded tomcat 中为外部静态 HTML 文件提供服务?

    我是 Spring 框架和 Spring Boot 的新手 我实现了一个非常简单的 RESTful Spring Boot Web 应用程序 您可以在另一个问题中看到几乎完整的源代码 Spring Boot 如何外部化 JDBC 数据源配置
  • java.awt.Desktop 类

    我正在使用适用于 Android 的 Google API 由于适用于 Android 的 Google API G Suite Quickstart 引用了他们的 java 示例 因此我正在尝试实现此功能 GoogleAuthorizat
  • PHP 增加一半

    我有一个简单的问题 可能很容易回答 我已经搜索过 但不确定我是否搜索正确或什么 不管怎样 使用PHP 我怎样才能将增量减半呢 例如 我知道我可以使用以下循环
  • 选择 2 个带有国旗的国家/地区下拉列表

    有人有一个易于使用的国家 地区下拉列表示例 带有国旗 用于Select2 我即将实施一个基于this建议 但我宁愿避免重新发明轮子 我正在研究类似的问题 这就是我的解决方法 function function var isoCountrie
  • DownloadManager 发送 STATUS_SUCCESSFUL 下载失败

    好的 我正在下载文件 图像 下载完成后 我想发送一条带有图像本地 URI 的消息 但有 20 的时间我会得到这样的信息 6 01 18 46 39 900 INFO DownloadManager 412 Initiating reques
  • 使用 JavaScript 遍历 JSON 对象树的所有节点

    我想遍历 JSON 对象树 但找不到任何库 看起来并不困难 但感觉就像重新发明轮子 在 XML 中 有很多教程展示如何使用 DOM 遍历 XML 树 如果你认为 jQuery 是一种overkill对于这样一个原始的任务 你可以这样做 yo
  • 如何创建一个将数字转换为双射十六进制的函数?

    也许我的数学不够好 但我在将数字转换为纯字母顺序时遇到问题双射十六进制就像 Microsoft Excel OpenOffice Calc 的做法一样 这是我的代码的一个版本 但没有提供我需要的输出 var toHexvg function
  • 如何在 Django 模板中使用 Jquery/Ajax 正确刷新 div

    我尝试过实施该解决方案here 但我似乎无法让它正常工作 我有一个 div 它是使用 Django 模板内的循环填充的 就在其下方 有一个输入框 我可以在其中输入一些文本 然后单击 提交 Submit 操作应该触发一个 Jquery 脚本
  • Spring安全Java配置

    我正在尝试使用 JavaConfig 而不是 Spring Security 的 XML 配置 我想用 PreAuthorization用于声明访问权限 我的 Spring 安全配置如下所示 Configuration EnableWebS
  • 在 Django 管理中编辑组对象时将用户对象分配给组

    在用户对象 编辑用户 的默认 Django 管理视图中 可以编辑用户的组成员身份 如果我也想反过来怎么办 IE 在群组编辑页面中 可以选择属于正在编辑的群组的用户 正如我所看到的 Django 没有从 Group 到 User 对象的 Ma
  • 将外键作为主键可以吗?

    我有两张桌子 用户 用户名 密码 个人资料 个人资料 ID 性别 出生日期 目前我正在使用这种方法 每个配置文件记录都有一个名为 userId 的字段 如下所示外键它链接到用户表 当用户注册时 会自动创建他的个人资料记录 我对我朋友的建议感
  • Symfony2 中的路由:可选参数 en 四个 url 用于一个路由

    在我的 Symfony2 应用程序中 我希望通过一条路由可以实现四个 url 很多其他的东西 报告 20 负数 很多其他的东西 报告 40 正数 很多其他的东西 报告 无号码 很多其他的东西 报告 没有数字 也没有 我的路线目前如下所示 r
  • WPF ListView 始终显示完整项目

    我有一个带有多个 ListView 控件的应用程序 其中要求 ListView 中的项目必须完全可见 列表中永远不应该显示部分 ListViewItem 如果用户在最终显示部分项目的位置释放 ScrollViewer 则列表应 捕捉 并自行
  • 如何使用 Apple SDK 以编程方式检测并连接到 Wifi 网络

    我想知道如何以编程方式检测并连接到 Wifi 网络 就像 Apple Store 中的 WifiFoFum 应用程序一样 该应用程序已获得批准并最近更新 因此必须有合法的方式来执行此操作 如果有人知道任何方法 请发布一个代码片段 即使它是一
  • CustomValidator ServerValidate 方法不触发

    我已经放了一个CustomValidator在我的表格上 我还没有设置它ControlToValidate财产 在其ServerValidate事件我写了以下内容 protected void CustomValidator1 Server
  • 从 ListView 中删除所选项目

    如何从列表视图中删除选定的项目 foreach ListViewItem eachItem in listView1 SelectedItems listView1 Items Remove eachItem 其中 listView1 是列
  • x86 上成功的未对齐访问的实际效果是什么?

    我总是听说未对齐的访问很糟糕 因为它们会导致运行时错误并使程序崩溃或减慢内存访问速度 然而 我找不到任何关于它们会减慢速度的实际数据 假设我在 x86 上并且有一些 但未知 未对齐访问的份额 实际上可能的最严重的减速是什么 在不消除所有未对
  • 为什么 == 在比较使用相同 int 值装箱的两个对象类型变量时不起作用

    在尝试用 C 实现一个简单的单链表时 我注意到 在比较用 int 值装箱的两个对象类型变量时不起作用 但是 Equals works 想检查一下为什么会这样 下面的代码片段是通用对象类型数据属性 public class Node