The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Email Subscription

    Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 717 other subscribers

Archive for May 26th, 2010

.NET/C#: comparison is a 101, or isn’t it?

Posted by jpluimers on 2010/05/26

In C# (well, actually: .NET), there are a couple of ways to compare things:

  • the built-in equality operator (==) which translates to the IL instruction CEQ
  • an overloaded equality operator (operator ==) that a class or struct can introduce
  • the virtualĀ Equals method that is introduced in System.Object and which you need to call explicitly

Sometimes, this leads to confusion, for instance,Ā given

[sourcecode language=”csharp”]
object one = 0;
object two = 0;
bool same = one == two;
[/sourcecode]

what would you expect the value of same to be?

Actualy, the value is false.

Why?

The reason is that the operator == does not call the System.Object.Equals method.
So theĀ System.Int32.Equals method is never called.

What happens in stead, is that the CEQ instruction is called.
Since both the integer zero values have beenĀ boxed into two objects (referred to by one and two), the CEQ will perform the comparison on the object references.
Even though both zero values are the same, both objects have a reference to a different spot in memory (the contents of both memory spots then are the same zero value).
Since one and two refer two different memory locations, the value of same becomes false.

Similar things hold for most types, unless they overload the operator ==.

System.String is a special type.
Even though it not a value type (it is derived from System.Object, not SystemValueType), it behaves like a value type.

One of the things that string does is overload the operator == (and overload the operator !=):

[sourcecode language=”csharp”]
public static bool operator ==(string a, string b)
{
return Equals(a, b);
}
[/sourcecode]

So even though one and two are potentially* referring to different locations, their content is compared, and same becomes true.

[sourcecode language=”csharp”]
string one = "Foo";
string two = "Foo";
bool same = one == two;
[/sourcecode]

*Now lets see these memory locations:

[sourcecode language=”csharp”]
object one = "Foo";
object two = "Foo";
bool same = one == two;
[/sourcecode]

Surprise! Here too, same becomes true.

What happened here is that when the compiler compiles two identical strings into an assembly, they are interned and end up at the same memory location.

Conclusion:

Comparison in .NET is not always 101.
It depends on the types involved, value types versus reference types, boxing, interning and the overloaded operator ==.

–jeroen

viaĀ The Lounge – CodeProject.

PS:
Another special thing about strings is thatĀ they are immutable:

A String object is called immutable (read-only) because its value cannot be modified once it has been created. Methods that appear to modify a String object actually return a new String object that contains the modification. If it is necessary to modify the actual contents of a string-like object, use the System.Text.StringBuilder class.

via String Class (System).

PS2:

Some other interesting links on comparison, interning, etc:

Posted in .NET, C#, Development, Software Development | Leave a Comment »