views:

75

answers:

2

How can i soth below arraylist according to int value. But if you compiled below codes error : Invalid Operation Exception... Detail : Failed to compare two elements in the array.

namespace SortArray
{
    class Program
    {
        static void Main(string[] args)
        {
            ArrayList otomobil = new ArrayList();
            otomobil.Add(new Otomobil() { Model = 2000, Marka = "mercedes", Renk = "Kırmızı" });
            otomobil.Add(new Otomobil() { Model = 2002, Marka = "Opel", Renk = "Yeşil" });
            otomobil.Add(new Otomobil() { Model = 2009, Marka = "Audi", Renk = "Mavi" });

            otomobil.Sort();
            for (int i = 0; i < otomobil.Count; i++)
            {
                Console.WriteLine(otomobil[i].ToString());
            }

        }
    }

    public class Otomobil
    {
        public string Marka { get; set; }
        public int Model { get; set; }
        public string Renk { get; set; }

        public Otomobil()
        {

        }

        public override string ToString()
        {
            return Marka + "(" + Model.ToString() + "-" + Renk + ")";
        }

        public int CompareTo(object obj)
        {
            if (obj == null)
                return 1;


            Otomobil outer = obj as Otomobil;
            if (outer == null)
                throw new ArgumentException();

            if (this.Model > outer.Model)
                return 1;
            else if (this.Model < outer.Model)
                return -1;
            else return 0;
        } 
    }
}
+4  A: 

class Otomobil : IComparable

STO
A: 

Here is a generic comparer that I use pretty regularly:

public class GenericComparer<T> : IComparer<T>
 {
     public string SortExpression { get; set; }
     public int SortDirection { get; set; } // 0:Ascending, 1:Descending

     public GenericComparer(string sortExpression, int sortDirection)
     {
         this.SortExpression = sortExpression;
         this.SortDirection = sortDirection;
     }
     public GenericComparer() { }

     #region IComparer<T> Members
     public int Compare(T x, T y)
     {
         PropertyInfo propertyInfo = typeof(T).GetProperty(SortExpression);
         IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null);
         IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null);

         if (SortDirection == 0)
         {
             return obj1.CompareTo(obj2);
             }
         else return obj2.CompareTo(obj1);
     }
     #endregion
 }

To use this:

class Program
{
    static void Main(string[] args)
    {
        List<Otomobil> otomobil = new List<Otomobil>();
        otomobil.Add(new Otomobil() { Model = 2000, Marka = "mercedes", Renk = "Kırmızı" });
        otomobil.Add(new Otomobil() { Model = 2002, Marka = "Opel", Renk = "Yeşil" });
        otomobil.Add(new Otomobil() { Model = 2009, Marka = "Audi", Renk = "Mavi" });

        otomobil.Sort(new GenericComparer<Otomobil>("Model", 0 /* ASC */));
        foreach(var item in otomobil)
        {
            Console.WriteLine(item.ToString());
        }

    }
}

I like this class, and use it regularly in ASP.NET, because I can then use (int)SortDirection.Ascending instead of 0 as the second parameter, which makes it slightly easier to read.

You could pretty easily modify this GenericComparer class to accept a Func<> parameter instead of a string to make it refactor-friendly. Of course, this will only work on properties that implement IComparable.

Jim Schubert