为什么 ReferenceEquals 和 == 运算符的行为与 Equals 不同

2023-12-12

我有一个实体,它不会覆盖任何平等成员\运算符。
当比较它们的两个代理时(我从Nhibernate session) 结果根据相等方法变化:

  • ReferenceEquals(第一,第二) - false。
  • 第一个 == 第二个 - false
  • 等于(第一,第二)- true。

这更奇怪,因为它们都存在于同一会话上下文中,并且根据休眠文档:

NHibernate 仅保证同一性( a == b ,默认值 在单个 ISession 中实现 Equals())!`

And:

该实例当前与持久性上下文关联。它 有一个持久的身份(主键值),并且也许有一个 数据库中的相应行。为了一份特别的坚持 上下文中,NHibernate 保证持久标识是等价的 CLR 标识(对象在内存中的位置)。

那么为什么不是所有的相等方法都返回 true 呢?


Update:
我以这种方式获取实体,查询子实体的会话并使用 Linq 获取父实体select,类似于:

var childs = session.Query<Child>();
var parents = childs.Select(x => x.ParentEntity).ToList(); 

Edit

您可能正在使用结构?见下文


我认为引用类型显示了您期望的行为:

public class Program    {
    class X { int x,y; }    
    public static void Main(string[] args)
    {
        X a = new X();
        X b = new X();
        System.Console.WriteLine(a == b);
        System.Console.WriteLine(a.Equals(b));
        System.Console.WriteLine(Equals(a,b));
        System.Console.WriteLine(ReferenceEquals(a,b));
} }

Prints:

False
False
False
False

对于结构体,情况有所不同(a==b测试,它不编译结构:)

public class Program {
    struct X { int x,y; }
    public static void Main(string[] args)
    {
        X a = new X();
        X b = new X();
        //System.Console.WriteLine(a == b);
        System.Console.WriteLine(a.Equals(b));
        System.Console.WriteLine(Equals(a,b));
        System.Console.WriteLine(ReferenceEquals(a,b));
} }

Output:

True
True
False

理由:

Equals() 的默认实现来自类ValueType,它是所有值类型的隐式基类。您可以通过在结构中定义自己的 Equals() 方法来覆盖此实现。ValueType.Equals()当比较不同(动态)类型的对象时,总是返回 false。如果对象属于同一类型,它通过调用来比较它们Equals()对于每个字段。如果其中任何一个返回 false,则整个过程停止,最终结果为 false。如果所有逐字段比较都返回 true,则最终结果为 true

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

为什么 ReferenceEquals 和 == 运算符的行为与 Equals 不同 的相关文章

随机推荐

  • 没有对 .m matlab 文件进行 git CRLF 转换?

    即使在 Windows 上 Matlab m 文件也使用 Unix LF 行结尾 我希望设置 git 配置文件 以便 m 文件not像其他常规文本文件一样转换回 CRLF 即我使用 LF 作为存储库中的默认样式 即使它是 Windows 这
  • 为什么对象类型的引用变量用作其他对象类型时必须进行强制转换

    虽然Java中的所有类都是Object类的子类 但与其他对象类型不同 Object类型的引用变量在没有强制转换的情况下不能分配给任何其他引用类型 例如 public class Inheritance public static class
  • 始终在 rootViewController 处打开应用程序

    在我的应用程序中 我希望用户始终看到rootViewController即使应用程序尚未完全终止 打开应用程序时的视图也是如此 我考虑过的一种选择是打电话abort in applicationWillResignActive 但这似乎不是
  • Java 和 SQLite 之间的时间戳差异

    你好 我有 SLQLite 数据库 其中有表 water logs CREATE TABLE water logs id INTEGER PRIMARY KEY AUTOINCREMENT amount REAL NOT NULL icon
  • 多显示器/双显示器系统上的 window.open() - 窗口在哪里弹出?

    在多显示器系统上使用 javascript window open 时 如何控制弹出窗口打开哪个显示器或显示空间中的哪个位置 对我来说 它似乎失去了控制 而且它的行为是随机的 window open 双屏 搜索的结果揭示了这个奇特的金块 双
  • Discord py 向频道发送消息

    我正在尝试使用 Discord py 库将消息从一个通道发送到另一个通道 想法 通道 1 用户无权读取和发送通道 2 中的消息 我尝试编写应该发送这些消息的机器人 例如 用户编写 发送 channel2 hello 机器人将此消息发送到通道
  • 在 Python 中使用 BeautifulSoup 从 HTML 脚本标签中提取 JSON

    我有以下 HTML 我应该如何从变量中提取 JSON window INITIAL STATE
  • Mac OS X Cocoa 多视图应用程序导航

    我已经花了整整 2 天的时间试图弄清楚如何使用 NSViewControllers 来创建多视图应用程序 这就是我所做的 我有 2 个视图控制器和 MainMenu xib 的窗口 我还有一个 AppController 它是两个视图控制器
  • python whois Windows 版

    我尝试在 python 中获取 whois 我用这个http code google com p pywhois 但它只能在linux下运行 可以在windows上运行吗 目前我收到错误 因为使用了内部linux命令whois 在 Wind
  • 创建鼠标聚光灯

    我正在尝试创建一个简单的应用程序 将聚光灯放在鼠标光标位置周围 使其他所有内容变暗 并用鼠标移动聚光灯 像这样的东西 我对 Qt 没有太多经验 我开始于这个例子 却走不了多远 我创建了一个位于顶部的窗口并设置了其不透明度 但我不知道如何使其
  • 调用一个函数,每个元素都是 Databricks 中的一个流

    我在 Databricks 中有一个 DataFrame 流 我想对每个元素执行一个操作 在网上我找到了特定目的的方法 比如将其写入控制台或转储到内存中 但我想添加一些业务逻辑 并将一些结果放入Redis中 更具体地说 这就是非流情况下的样
  • 如何以编程方式发现 git 使用的跨平台编辑器?

    假设我们在 Python 环境中 我们可以在 Windows OSX 或 Linux 上 我们如何确定git使用的编辑器 如果只是环境变量 我们可以这样做 os getenv GIT EDITOR 但它也可能在配置中 可以解析 git 配置
  • JSF 属性引用生命周期比目标作用域视图更短的作用域中的对象

    我有一个视图范围的托管 bean 其托管属性绑定到查询字符串参数 JSF 给了我熟悉的异常 javax faces FacesException Property reset references object in a scope wit
  • 字符串到日期转换返回错误值

    我正在尝试将字符串转换为日期 但返回值是错误的 String startDate 2013 07 24 Date date new Date try DateFormat formatter new SimpleDateFormat yyy
  • json.Marshal(struct) 返回“{}”

    type TestObject struct kind string json kind id string json id omitempty name string json name email string json email f
  • getActionBar() 返回 Null (AppCompat-v7 21)

    在我将 AppCompat v7 更改为 21 0 0 并且编译没有问题后 我的应用程序在运行时就崩溃了 它给了我错误 java lang NullPointerException Attempt to invoke virtual met
  • 使用 Android 服务处理网络连接

    我正在开发一个 Android 应用程序 需要保持与聊天服务器的网络连接 我知道我可以创建一个服务来启动与服务器的连接 但是该服务如何通知 Android 活动新传入的消息 活动需要更新视图以显示新消息 我对 Android 还很陌生 所以
  • 如何使用 Spring Security 重定向到拒绝访问页面

    我有一个使用 JSF Spring 的应用程序 我正在使用 spring security 并且工作正常 但是 当我尝试在没有身份验证的情况下访问安全页面时 我只是显示 403 禁止页面 而不是将我重定向到被拒绝的页面 我不知道 appli
  • 如何获取数组键是否受保护?

    我有这种类型的数组 我想获取数组元素 context course Object id protected gt 15 contextlevel protected gt 50 instanceid protected gt 2 path
  • 为什么 ReferenceEquals 和 == 运算符的行为与 Equals 不同

    我有一个实体 它不会覆盖任何平等成员 运算符 当比较它们的两个代理时 我从Nhibernate session 结果根据相等方法变化 ReferenceEquals 第一 第二 false 第一个 第二个 false 等于 第一 第二 tr