using System; using System.Collections.Generic; using System.Text.RegularExpressions; namespace Wayne.Lib { /// <summary> /// Class representing a version number. /// </summary> public class VersionNumber : IComparable<VersionNumber>, IEquatable<VersionNumber> { #region Fields private const char Dot = '.'; private static readonly Regex re = new Regex(@"^\d+(\.\d+)*$"); private readonly string versionString; #endregion #region Construction /// <summary> /// Constructor /// </summary> /// <param name="versionString">Version string that is on a proper version number format.</param> /// <exception cref="ArgumentException">If versionString is not on correct Version number format.</exception> public VersionNumber(string versionString) { if (!re.IsMatch(versionString)) { throw new ArgumentException(versionString + " is not a valid version string"); } this.versionString = versionString; } #endregion #region Methods /// <summary> /// CompareTo method /// </summary> /// <param name="other"></param> /// <returns></returns> public int CompareTo(VersionNumber other) { Stack<int> ps = Convert(this.ToString()); Stack<int> qs = Convert(other.ToString()); // Continue while they are equal while (ps.Count > 0 && qs.Count > 0) { int p = ps.Pop(); int q = qs.Pop(); if (p < q) { return -1; } if (p > q) { return 1; } } // Check who ran out if (ps.Count == 0 && qs.Count == 0) { // both ran out, they are equal return 0; } if (ps.Count > 0 && qs.Count == 0) { // right ran out, so left must be bigger return 1; } if (ps.Count == 0 && qs.Count > 0) { // left ran out, so right must be bigger return -1; } // Should never end up here... throw new ArgumentException("this cannot happen"); } private static Stack<int> Convert(string fullString) { List<int> list = new List<int>(); foreach (string number in fullString.Split(Dot)) { list.Add(int.Parse(number)); } list.Reverse(); return new Stack<int>(list); } /// <summary> /// ToString method /// </summary> /// <returns></returns> public override string ToString() { return versionString; } /// <summary> /// Equals method /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { VersionNumber otherVersionNumber = obj as VersionNumber; if (otherVersionNumber != null) return this.Equals(otherVersionNumber); else return false; } /// <summary> /// Equals method /// </summary> /// <param name="other"></param> /// <returns></returns> public bool Equals(VersionNumber other) { return this.CompareTo(other) == 0; } /// <summary> /// Hash code generation /// </summary> /// <returns></returns> public override int GetHashCode() { return versionString.GetHashCode(); } #endregion } }