ようこそ。睡眠不足なプログラマのチラ裏です。

IComparableインターフェイスを利用したソート

独自クラスについてソートをしたいような場合、対象クラスにIComparableインターフェイスを実装し、
それをCollectionにぶち込んでSort()メソッドを呼び出すことで、簡単にソートすることができる。
たぶん、staticなジェネリックメソッドを作成してIComparableを実装していさえすれば
なんでもソートできるようにするのがセオリくさい。


下記にIComparableを実装したクラス例を示します。

■仕 様
・(TopBust - UnderBust) によりカップを割り出します。
・カップを比較し大きい方をバストが大きいとします。
・カップが等しい場合、(TopBust - UnderBust)が大きい方をバストが大きいとします。
・(TopBust - UnderBust)も等しい場合、TopBustが大きい方をバストが大きいとします。
・カップサイズ、(TopBust - UnderBust)、TopBustの大きさのいずれも等しい場合、バストサイズが同じとします。


むしゃくしゃしてやった、今は反省している(棒読み)

    public class Female : IComparable<Female>,INullable, INotifyPropertyChanged    
    {

        #region 列挙体
        /// <summary>
        /// Kカップを最大とするバストサイズ
        /// </summary>
        public enum ECup
        {
            None,
            AAA,
            AA,
            A,
            B,
            C,
            D,
            E,
            F,
            G,
            H,
            I,
            J,
            K
        }
        #endregion

        #region メンバ
            private string name;
            private double underBust;
            private double topBust;
            private ECup cup = ECup.AAA ; 
        #endregion

        #region コンストラクタ
        
            public Female(){
                cup = ECup.None;              
            }
        
            /// <summary>
            /// コンストラクタ
            /// </summary>
            /// <param name="unserBust">アンダーバスト</param>
            /// <param name="topBust">トップバスト</param>
            public Female(string name,double under, double top)
            {
                if (under <= 0) { throw new ApplicationException("アンダーバストが不正な値です。"); }
                if (top <= 0) { throw new ApplicationException("トップバストが不正な値です。"); }
                if (top < under) { throw new ApplicationException("アンダーバストよりもトップバストの方が大きい必要があります。"); }
            
                //名前
                this.name = name;
            
                //アンダーバスト
                this.underBust = under;
                //トップパスト
                this.topBust = top;
            }
        #endregion

        #region プロパティ
        
            /// <summary>
            /// 名前
            /// </summary>
            public string Name{
                get{
                    return name;
                }
            }
        
            /// <summary>
            /// アンダーバスト
            /// </summary>
            public double UnderBust
            {
                get{
                    return this.underBust;         
                }
                set{
                  this.underBust = value;
                  this.NotifyPropertyChanged("UnderBust");
                }
            }
            
            /// <summary>
            /// トップバスト
            /// </summary>
            public double TopBust
            {
                get{
                    return this.topBust;
                }
                set
                {
                    this.topBust = value;
                    this.NotifyPropertyChanged("TopBust");
                }
            }
            
            /// <summary>
            /// カップサイズ
            /// </summary>
            public virtual ECup Cup{
                get{
                    double bust = TopBust - UnderBust;

                    if (cup ==ECup.None){return cup;}
                    
                    if (bust < 7.5){
                        //AAAカップ
                        cup = ECup.AAA;                    
                    }else if (bust >=7.5 && bust <10.0){
                        //AAカップ
                        cup = ECup.AA;
                    }else if(bust >=10.0 && bust <12.5){
                        //Aカップ
                        cup = ECup.A;
                    }else if (bust >=12.5 && bust <15){
                        //Bカップ
                        cup = ECup.B;
                    }else if (bust >=15 && bust <17.5){
                        //Cカップ
                        cup = ECup.C;
                    }else if (bust >=17.5 && bust < 20){
                        //Dカップ
                        cup = ECup.D;
                    }else if (bust >= 20 &&  bust <22.5){
                        //Eカップ
                        cup = ECup.E;
                    }else if (bust >= 22.5 && bust < 25){
                        //Fカップ
                        cup = ECup.F;
                    }else if (bust >= 25 && bust <27.5){
                        //Gカップ
                        cup = ECup.G;
                    }else if (bust >=27.5 && bust < 30){
                        //Hカップ
                        cup = ECup.H;
                    }else if (bust >=30 && bust < 32.5){
                        //Iカップ
                        cup = ECup.I;
                    }else if (bust >=32.5 && bust <35){
                        //Jカップ
                        cup = ECup.J;                        
                    }else if (bust >=35){
                        //Kカップ
                        cup = ECup.K;
                    }else{
                        cup = ECup.K;
                    }
                    
                    return cup;
                }
            }
                        
        #endregion

        #region オーバーライド
        public override string ToString()
        {
            return this.Name;
        }
        #endregion

        #region メソッド
        
        public string GetStatus(){
            double aaa = (TopBust - UnderBust);
            return this.Cup.ToString() + "カップ(トップとの差" + aaa.ToString() + "cm)";
        }
        
        #endregion

        #region IComparableの実装
            /// <summary>
            /// 指定したオブジェクトまたは値型とこのインスタンスとを比較し、これらの相対値を示す値を返します。 
            /// </summary>
            /// <param name="other">比較対象</param>
            /// <returns>比較相対値</returns>
            public int CompareTo(Female other)
            {
                int cupCompareResult = this.Cup.CompareTo(other.Cup);
                if (cupCompareResult == 0)
                {
                    //カップサイズが同じだった場合、アンダーとトップの差の比較結果を返す
                    double thisBust = (this.TopBust - this.UnderBust);
                    double otherBust = (other.TopBust - other.UnderBust);
                    if (thisBust.CompareTo(otherBust) == 0){
                        //アンダーとトップの差が等しかった場合は、TopBustの大きさの比較結果を返す
                        return this.TopBust.CompareTo(other.TopBust);
                    }else{
                        return thisBust.CompareTo(otherBust);
                    }
                }
                //カップサイズの比較結果を返す
                return cupCompareResult;
            }
        #endregion

        #region INotifyPropertyChangedの実装

            public event PropertyChangedEventHandler PropertyChanged;


            protected virtual void NotifyPropertyChanged(string propertyName)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        
        #endregion

        #region INullableの実装

        public bool IsNull
        {
            get{
                return true;
            }
        }

        #endregion
        
    }