C# 中 Object == Object 安全吗

问题描述 投票:0回答:2

在 Java 中,以下代码可能返回 false:

IntegerPlus o1 = new IntegerPlus(1000);
IntegerPlus o2 = o1;

boolean b1 = o1 == o2;
boolean b2 = o1.Equals (o2);

这在C#中也是一个问题吗?或者 C# 执行 == 的方式是否始终为 true,即使对象被移动? (我在这里更详细地描述了 Java 问题。

c# object equality
2个回答
2
投票

不。

在 C#/.Net 中,哈希码不参与

==
!=
Equals
的默认实现。如果对象是引用类型并且由 GC 移动,则该对象之外没有任何内容会影响默认比较。

编辑:下面与比较无关的细节。

==
Equals
彼此没有关系(除非按照惯例)。

在 C# 中,您有 operator == 类/结构可以重载。默认行为是比较引用类型的引用,比较系统值类型的值,对于自定义“结构”,没有自动生成的

==
运算符。请注意,另一个比较
Equals
不涉及
operator ==
的默认定义。

对于预定义值类型,相等运算符 (==) 如果其操作数的值相等则返回 true,否则返回 false。对于字符串以外的引用类型,如果两个操作数引用同一个对象,则 == 返回 true。

您还可以为课程提供您的自定义

Object.Equals
。对于重新定义
==
Equals
的类,良好的做法是重新定义所有与比较相关的方法,使其一致地工作(
==
!=
Equals(object other)
GetHashCode
;可能是
Equals(myType other)
)。

.Net 中

GetHashCode
的唯一用途是基于哈希的集合,例如
Dictionary
HashSet
。检查 C# 中的 GetHashCode 指南

自定义比较的明显示例是

System.String
(
string
) - 它是引用类型,但与比较相关时表现为常规值类型。

回到原始示例:

  • 如果
    IntegerPlus
    struct
    ,没有自定义“==”/
    Equals
    :没有自动创建
    ==
    new IntegerPlus(42) == new IntegerPluss(42)
    - 语法错误)。您可以获得
    Equals
    (自动提供)的所有字段的值比较。
  • 如果
    IntegerPlus
    是不提供自定义
    class
    operator ==
    Equals
    ,您将获得参考比较和
    new IntegerPlus(42) != new IntegerPluss(42)
    ,与
    Equals
  • 相同
  • 如果
    IntegerPlus
    仅提供
    ==
    !=
    Equals
    之一,则行为将由自定义实现定义(外部观察者可能无法解释)
  • 如果
    IntegerPlus
    是值类型或引用类型,并提供所有 4 个比较相关方法的一致集,您可以获得值比较行为

1
投票

在 Java 中,

==
运算符对于所有可编译的操作数组合都是安全的,并且只要操作数既不是
float
也不是
double
,它将实现等价关系。随着自动装箱的出现,这不再是正确的,因为不幸的是,原语与其包装的等效项之间的合法比较并不安全,并且以与单独类型定义的等价关系不一致的方式扩展了
==
运算符。

虽然当两个操作数都是引用类型时 Java 将测试的等价关系(即引用等价)并不总是程序员感兴趣的,但

==

 的行为与引用类型一致。如果变量 x、y 和 z 是引用类型的任意组合,并且表达式 x==y、y==z 和 x==z 全部编译,则在其中两个为 true 的每种情况下,第三个也将是.

在 C# 中,

==

 标记用于表示两个不同的运算符:可重载相等测试和默认引用相等测试。如果 
==
 的操作数之一定义了适用于所提供操作数的特定
组合的重载,则该标记将被解释为可重载的相等测试运算符。否则,如果操作数是兼容的引用类型,它将被解释为默认的引用相等测试运算符。由于两个运算符使用相同的标记,并且它们具有不同的语义,因此它通常无法在引用类型之间实现可靠的等价关系,除非所讨论的类型都没有重载它来表示除引用相等之外的任何内容。

给定定义

String s1=123.ToString(); String s2=123.ToString(); Object o = s1;

,比较
s1==s2
将返回True(使用
(string,string)
==
重载,它会看到它们包含相同的字符),并且
o==s1
将返回true(使用默认引用- 等价运算符以查看它们
是同一个对象),但 
o==s2
 将返回 false(使用默认的引用等价运算符来查看它们是不同的对象)。

如果

==

 的两个操作数都是 
Object
 类型,那么它将表现为引用相等测试;但是,如果它们是其他类型,则该运算符有时可能表现为引用相等测试,有时则表现为其他类型。

© www.soinside.com 2019 - 2024. All rights reserved.