在C#中Object == Object是否安全?
在Java中,以下代码可以返回false:
IntegerPlus o1 = new IntegerPlus(1000); IntegerPlus o2 = o1; boolean b1 = o1 == o2; boolean b2 = o1.Equals (o2);
这也是C#中的一个问题吗? 或者C#是否以某种方式执行==即使对象被移动也总是如此? ( 我在这里更详细地描述了Java问题。 )
没有。
在C#/。中,Net哈希代码不涉及==
, !=
或Equals
默认实现。 如果object是引用类型并且它被GC移动,则此对象外部没有任何内容会影响默认比较。
编辑 :以下有关比较的无关详细信息。
==
和Equals
彼此无关(按惯例除外)。
在C#中你有operator == class / struct可以重载。 默认行为是比较引用类型的引用,系统值类型的值比较和自定义’struct’,没有自动生成的==
运算符。 请注意,其他比较Equals
不涉及operator ==
默认定义。
对于预定义的值类型,如果操作数的值相等,则相等运算符(==)返回true,否则返回false。 对于除string之外的引用类型,如果其两个操作数引用同一对象,则==返回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
是不提供自定义operator ==
或Equals
你得到引用比较和new IntegerPlus(42) != new IntegerPluss(42)
和Equals
相同 - 如果
IntegerPlus
只提供==
,!=
,则Equals
行为将由自定义实现定义(外部观察者可能无法解释) - 如果
IntegerPlus
是值或引用类型,并提供所有4个比较相关方法的一致集合,则可以获得值比较行为
在Java中, ==
运算符过去对所有可编译的操作数组合都是安全的,并且如果操作数既不是float
也不是double
,它将实现等价关系。 随着自动装箱的出现不再那么真实,因为不幸的是 – 基元与它们包装的等价物之间的合法比较并不安全,并且以与单独定义的等价关系不一致的方式扩展了==
运算符。
虽然当两个操作数都是引用类型(即引用等价)时,Java将测试的等价关系并不总是程序员感兴趣的,但==
的行为与引用类型一致。 如果变量x,y和z是引用类型的任意组合,并且表达式x == y,y == z,并且x == z都是编译,那么在两个都为真的每种情况下,第三个也是如此。
在C#中, ==
标记用于表示两个不同的运算符:可重载的相等性测试和默认的引用相等性测试。 如果==
一个操作数定义了适用于所提供的操作数的特定组合的重载,则该标记将被解释为可重载的相等测试运算符。 否则,如果操作数是兼容的引用类型,则它将被解释为默认的引用相等性测试运算符。 因为两个运算符使用相同的标记并且它们具有不同的语义,所以它通常不能在引用类型之间实现可靠的等价关系,除非所讨论的类型都不会使其重载以表示除引用相等之外的任何其他类型。
给定定义String s1=123.ToString(); String s2=123.ToString(); Object o = s1;
String s1=123.ToString(); String s2=123.ToString(); Object o = s1;
,比较s1==s2
将返回True(使用s1==s2
的(string,string)
重载,它看到它们包含相同的字符),并且o==s1
将返回true(使用默认的引用等价运算符看到它们是同一个对象),但是o==s2
将返回false(使用默认的引用等价运算符来看它们是不同的对象)。
如果==
两个操作数都是Object
类型,那么它将表现为引用相等性测试; 但是,如果它们属于其他类型,那么运算符有时可能表现为参考相等性测试,有时也表现为其他类型。