Search code examples
c#structicomparable

How to implement IComparable<Time> in my Struct?


My code includes struct called Time.

I would like to implement IComparable<Time> interface in my struct to compare two variables of type 'Time'.

I've already did it with IEquatable and it works, but I can't figure out how to do it with IComparable.

Since Time consists of three variables (hours, min, sec) I can't simply consider each case in if. Or can I? Could you give me a hint how to code it? Thank you.

{    
    public struct Time : IEquatable<Time>, IComparable<Time>
    {
        private byte hours, minutes, seconds;

        public byte Hours { get { return hours; } }
        public byte Minutes { get { return minutes; } }
        public byte Seconds { get { return seconds; } }

        public Time(byte hh, byte mm, byte ss)
        {
            if (hh < 0 || hh > 24)
                throw new ArgumentOutOfRangeException();
            if (mm < 0 || mm > 60)
                throw new ArgumentOutOfRangeException();
            if (ss < 0 || ss > 60)
                throw new ArgumentOutOfRangeException();

            this.hours = hh;
            this.minutes = mm;
            this.seconds = ss;
        }

        public Time(byte hh, byte mm) : this(hh, mm, default(byte)) { }

        public Time(byte hh) : this(hh, default(byte), default(byte)) { }

        public Time(string hms)
        {
            string[] arr = hms.Split(':');

            this.hours = Convert.ToByte(arr[0]);
            this.minutes = Convert.ToByte(arr[1]);
            this.seconds = Convert.ToByte(arr[2]);
        }

        public override string ToString()
        {
            return Hours + ":" + Minutes + ":" + Seconds;
        }

        public override bool Equals(object t)
        {
            if (t == null || this.GetType() != t.GetType()) return false;

            return (this.Hours == ((Time)t).Hours &&
                this.Minutes == ((Time)t).Minutes &&
                this.Seconds == ((Time)t).Seconds);
        }

        public override int GetHashCode()
        {
            return this.GetHashCode();
        }

        // IEquatable
        public bool Equals(Time other)
        {
            return this.Equals((object)other);
        }

        public static bool operator == (Time t1, Time t2)
        {
            return t1.Equals(t2);
        }

        public static bool operator !=(Time t1, Time t2)
        {
            return !t1.Equals(t2);
        }

        // IComparable
        public int CompareTo(Time other)
        {
            if (this == other)
                return 0;

            // Code that compares two variables
        }

        public static bool operator > (Time t1, Time t2)
        {
            return t1.CompareTo(t2) == 1;
        }

        public static bool operator < (Time t1, Time t2)
        {
            return t1.CompareTo(t2) == -1;
        }

        public static bool operator >= (Time t1, Time t2)
        {
            return t1.CompareTo(t2) >= 0;
        }

        public static bool operator <= (Time t1, Time t2)
        {
            return t1.CompareTo(t2) <= 0;
        }
    }
}

Solution

  • public int CompareTo(Time other)
    {
        var by_hour = this.Hours - other.Hours;
        if (by_hour != 0)
            return by_hour;
    
        var by_minute = this.Minutes - other.Minutes;
        if (by_minute != 0)
            return by_minute;
    
        return this.Seconds - other.Seconds;
    }
    

    Also change all places where you use the Compare method to account for the fact that it can return non-zero values other than 1 and -1.