Generic Range<T> class

Friday, February 12, 2010 / Posted by Luke Puplett /

Here is my Range class used a project dealing heavily with time slots. A skinny post this as its in response to a request for example generic types from a discussion on LinkedIn.

Sorry about line wrapping.


namespace RootNs.ExampleCorp.Core
{
    using System;
    using System.Runtime.Serialization;

    /// <summary>
    /// Represents a range of some data type.
    /// </summary>
    /// <typeparam name="T">The type of data such as DateTime.</typeparam>
    [DataContract(Namespace = "http://schemas.ExampleCorp.tv/2008/11/app/entities/core")]
    public class Range<T> : System.ComponentModel.INotifyPropertyChanged where T: IComparable<T>
    {
        #region Constructors

        protected Range() { }

        public Range(T start, T stop)
        {
            _start = start; _stop = stop;
        }

        #endregion

        #region OnMethods

        /// <summary>
        /// Is called upon any property change.
        /// </summary>
        /// <param name="e">Args passed through to the PropertyChanged event.</param>
        protected virtual void OnPropertyChanged(System.ComponentModel.PropertyChangedEventArgs e)
        {
            //
            // Actually nothing here - this is more for derived types to override.

            this.RaisePropertyChanged(e);
        }

        /// <summary>
        /// Raises the PropertyChanged event.
        /// </summary>        
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design""CA1030:UseEventsWhereAppropriate")]
        protected void RaisePropertyChanged(System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (this.PropertyChanged != null) { this.PropertyChanged(this, e); }
        }

        #endregion

        #region Properties

        [DataMember(Order = 1)]
        public T Start 
        {
            get
            {
                return _start;
            }
            protected internal set
            {
                _start = value;
                this.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("Start"));
            }
        } private T _start;

        [DataMember(Order = 2)]
        public T Stop
        {
            get
            {
                return _stop;
            }
            protected internal set
            {
                _stop = value;
                this.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("Stop"));
            }
        } private T _stop;

        #endregion

        #region Methods

        public bool IsOverlapping(Range<T> range) { return this.IsOverlapping(range.Start, range.Stop); }

        public bool IsOverlapping(T start, T stop)
        {
            return ((this.Start.CompareTo(stop) < 0) && (start.CompareTo(this.Stop) < 0));
        }

        public bool IsOverlapping(T spot)
        {
            return this.IsEnveloping(spot);
        }

        public bool IsEnveloping(Range<T> range) { return this.IsEnveloping(range.Start, range.Stop); }

        public bool IsEnveloping(T spot)
        {
            return ((this.Start.CompareTo(spot) <= 0) && spot.CompareTo(this.Stop) <= 0);
        }            

        public bool IsEnveloping(T start, T stop)
        {
            return ((this.Start.CompareTo(start) <= 0) && (stop.CompareTo(this.Stop) <= 0));
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event System.ComponentModel.PropertyChangedEventHandler  PropertyChanged;

        #endregion

        #region Object Overrides

        /// <summary>
        /// Returns a string representation of the object.
        /// </summary>
        public override string ToString()
        {
            return String.Format("{0} - {1}"this.Start.ToString(), this.Stop.ToString());
        }

        /// <summary>
        /// Compares this with another for equality.
        /// </summary>        
        public override bool Equals(object obj)
        {
            if (obj == null) { return false; }
            Range<T> cast = obj as Range<T>;
            if (cast == null) { return false; }
            return this.Equals(cast);
        }

        /// <summary>
        /// Compares this with another for equality.
        /// </summary>
        public bool Equals(Range<T> comparison)
        {
            if (comparison == null) { return false; }
            return (bool)(comparison.ToString() == this.ToString());
        }

        // static Equals(obj, obj) actually calls the instance.Equals(obj) anyway so no need to implement.

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


        #endregion
    }
}

Labels:

0 comments:

Post a Comment