12.07.2015 Views

Accelerated

Accelerated

Accelerated

SHOW MORE
SHOW LESS
  • No tags were found...

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

392CHAPTER 13 ■ IN SEARCH OF C# CANONICAL FORMSYou should be aware of a few points when implementing IComparable.CompareTo. First, noticethat the return value specification says nothing about the actual value of the returned integer. Itonly defines the sign of the return values. So, to indicate a situation where this is less than obj, youcan simply return -1. When your object represents a value that carries an integer meaning, an efficientway to compute the comparison value is by subtracting one from the other. It can be temptingto treat the return value as an indication of the degree of inequality. Although this is possible, I don’trecommend it, since relying on such an implementation is outside the bounds of the IComparablespecification, and not all objects can be expected to do that.Second, keep in mind that CompareTo provides no return value definition for when two objectscannot be compared. Since the parameter type to CompareTo is System.Object, you could easilyattempt to compare an Apple instance to an Orange instance. In such a case, there is no comparison,and you’re forced to indicate such by throwing an ArgumentException object.Finally, semantically, the IComparable interface is a superset of Object.Equals. If you derivefrom an object that overrides Equals and implements IComparable, then you’re wise to both overrideEquals and reimplement IComparable in your derived class, or do neither. You want to make certainthat your implementation of Equals and CompareTo are aligned with each other.Based upon all of this information, a compliant IComparable interface should adhere to the followingrules:• x.CompareTo(x) must return 0. This is the reflexive property.• If x.CompareTo(y) == 0, then y.CompareTo(x) must equal 0. This is the symmetric property.• If x.CompareTo(y) == 0, and y.CompareTo(z) == 0, then x.CompareTo(z) must equal 0. This isthe transitive property.• If x.CompareTo(y) returns a value other than 0, then y.CompareTo(x) must return a non-0value of the opposite sign. In other terms, this statement says that if x < y, then y > x, orif x > y, then y < x.• If x.CompareTo(y) returns a value other than 0, and y.CompareTo(z) returns a value otherthan 0 with the same sign as the first, then x.CompareTo(y) is required to return a non-0 valueof the same sign as the previous two. In other terms, this statement says that if x < y and y y and y > z, then x > z.The following code shows a modified form of the ComplexNumber class that implementsIComparable and consolidates some code at the same time in private helper methods:using System;public sealed class ComplexNumber : IComparable{public ComplexNumber( double real, double imaginary ) {this.real = real;this.imaginary = imaginary;}public override bool Equals( object other ) {bool result = false;ComplexNumber that = other as ComplexNumber;if( that != null ) {result = InternalEquals( that );}}return result;

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

Saved successfully!

Ooh no, something went wrong!