15.02.2015 Views

C# 4 and .NET 4

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

operator overloading ❘ 163<br />

Comparison operator (==)<br />

It is best to think of the comparison operator as an intermediate option between strict value comparison <strong>and</strong><br />

strict reference comparison. In most cases, writing the following means that you are comparing references:<br />

bool b = (x == y); // x, y object references<br />

However, it is accepted that there are some classes whose meanings are more intuitive if they are treated<br />

as values. In those cases, it is better to override the comparison operator to perform a value comparison.<br />

Overriding operators is discussed next, but the obvious example of this is the System.String class<br />

for which Microsoft has overridden this operator to compare the contents of the strings rather than<br />

their references.<br />

Comparing Value Types for equality<br />

When comparing value types for equality, the same principles hold as for reference types:<br />

ReferenceEquals() is used to compare references, Equals() is intended for value comparisons, <strong>and</strong> the<br />

comparison operator is viewed as an intermediate case. However, the big difference is that value types need<br />

to be boxed to be converted to references so that methods can be executed on them. In addition, Microsoft<br />

has already overloaded the instance Equals() method in the System.ValueType class to test equality<br />

appropriate to value types. If you call sA.Equals(sB) where sA <strong>and</strong> sB are instances of some struct, the<br />

return value will be true or false, according to whether sA <strong>and</strong> sB contain the same values in all their<br />

fields. On the other h<strong>and</strong>, no overload of == is available by default for your own structs. Writing (sA ==<br />

sB) in any expression will result in a compilation error unless you have provided an overload of == in your<br />

code for the struct in question.<br />

Another point is that ReferenceEquals() always returns false when applied to value types because, to<br />

call this method, the value types need to be boxed into objects. Even if you write the following, you will still<br />

get the answer of false:<br />

bool b = ReferenceEquals(v,v); // v is a variable of some value type<br />

The reason for this is that v will be boxed separately when converting each parameter, which means you get<br />

different references. Because of this, there really is no reason to call ReferenceEquals() to compare value<br />

types because it doesn’t make much sense.<br />

Although the default override of Equals() supplied by System.ValueType will almost certainly be<br />

adequate for the vast majority of structs that you define, you might want to override it again for your own<br />

structs to improve performance. Also, if a value type contains reference types as fields, you might want<br />

to override Equals() to provide appropriate semantics for these fields because the default override of<br />

Equals() will simply compare their addresses.<br />

oPeraTor oVerloading<br />

This section looks at another type of member that you can define for a class or a struct: the operator overload.<br />

Operator overloading is something that will be familiar to C++ developers. However, because the concept<br />

will be new to both Java <strong>and</strong> Visual Basic developers, we explain it here. C++ developers will probably<br />

prefer to skip ahead to the main operator overloading example.<br />

The point of operator overloading is that you do not always just want to call methods or properties on<br />

objects. Often, you need to do things like adding quantities together, multiplying them, or performing<br />

logical operations such as comparing objects. Suppose that you had defined a class that represents a<br />

mathematical matrix. Now in the world of math, matrices can be added together <strong>and</strong> multiplied, just like<br />

numbers. Therefore, it is quite plausible that you would want to write code like this:<br />

Matrix a, b, c;<br />

// assume a, b <strong>and</strong> c have been initialized<br />

Matrix d = c * (a + b);<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!