Equality
When comparing for equality in C#, this refers to testing for equivalence in
some cases (also known as value equality), and in other cases it refers to
testing for reference equality, which tests whether two variables refer to the
same underlying object in memory. Every custom type can be compared for equality
because it inherits from System.Object
(or System.ValueType
for value types,
which inherits from System.Object
), using either one of the abovementioned
semantics.
For example, when comparing for equivalence and reference equality in C#:
var a = new Point(1, 2);
var b = new Point(1, 2);
var c = a;
Console.WriteLine(a == b); // (1) True
Console.WriteLine(a.Equals(b)); // (1) True
Console.WriteLine(a.Equals(new Point(2, 2))); // (1) False
Console.WriteLine(ReferenceEquals(a, b)); // (2) False
Console.WriteLine(ReferenceEquals(a, c)); // (2) True
record Point(int X, int Y);
-
The equality operator
==
and theEquals
method on therecord Point
compare for value equality, since records support value-type equality by default. -
Comparing for reference equality tests whether the variables refer to the same underlying object in memory.
Equivalently in Rust:
#[derive(Copy, Clone)]
struct Point(i32, i32);
fn main() {
let a = Point(1, 2);
let b = Point(1, 2);
let c = a;
println!("{}", a == b); // Error: "an implementation of `PartialEq<_>` might be missing for `Point`"
println!("{}", a.eq(&b));
println!("{}", a.eq(&Point(2, 2)));
}
The compiler error above illustrates that in Rust equality comparisons are
always related to a trait implementation. To support a comparison using ==
,
a type must implement PartialEq
.
Fixing the example above means deriving PartialEq
for Point
. Per default,
deriving PartialEq
will compare all fields for equality, which therefore have
to implement PartialEq
themselves. This is comparable to the equality for
records in C#.
#[derive(Copy, Clone, PartialEq)]
struct Point(i32, i32);
fn main() {
let a = Point(1, 2);
let b = Point(1, 2);
let c = a;
println!("{}", a == b); // true
println!("{}", a.eq(&b)); // true
println!("{}", a.eq(&Point(2, 2))); // false
println!("{}", a.eq(&c)); // true
}
See also:
Eq
for a stricter version ofPartialEq
.