Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Array.Sort()


Автор: Sash_79 11.11.2007, 14:05
привет! не получается разобраться с Array.Sort(), мне необходимо произвести сортировку по двум показателям,для использования сортировки по второму показателю использую интерфейс IComparer  и вспомогательный класс  SortBy. Так вот компилятор ругается, на 
Array.Sort(mas, new SortBy()); говорит что вместо new SortBy() необходим параметр типа Array.Хотя в книге говориться,что System.Array предусматривает множество вариантов Sort(),и один из них,как раз и должен принимать объект реализующий IComparer
 Что делать?smile
using System;
using System.Collections.Generic;
using System.Text;
//using System.Collections;

namespace glava4_sravnenie
{
    interface IComparer
    {
        int Compare(object m1, object m2);
    }
    public class SortBy : IComparer
    {
        public SortBy() { }
        int IComparer.Compare(object m1, object m2)
        {
            car t1 = (car)m1;
            car t2 = (car)m2;

            return String.Compare(t1.name, t2.name);
        }
    }
    public class car : IComparable
    {
        public int id;
        public string name;

        public car(int id, string name)
        {
            this.id = id;
            this.name = name;
        }

        int IComparable.CompareTo(object o)
        {
            car temp = (car)o;
            if (this.id > temp.id)
                return 1;
            if (this.id < temp.id)
                return -1;
            else
                return 0;
        }

    }
    class work
    {
        static void Main(string[] args)
        {
            car[] mas = new car[3];

            mas[0] = new car(79, "Mers");
            mas[1] = new car(25, "ABMW");
            mas[2] = new car(25, "Opel");

            Console.WriteLine("Ne otsortirovannui massive:");
            foreach (car c in mas)
            {
                Console.WriteLine(c.id + " " + c.name);
            }


            Array.Sort(mas, new SortBy());


            Console.WriteLine("A teper otsortirovannui:");
            foreach (car c in mas)
            {
                Console.WriteLine(c.id + " " + c.name);
            }
          
            Console.ReadLine();

        }
    }
}

Автор: thomas 11.11.2007, 17:09
Sash_79
Надо сначала создать обьект сравнения, а потом его подставлять в качестве параметра в метод Sort().
Ошибка записи 
Код

Array.Sort(mas, new SortBy());


Надо что то типа
Код

SortBy mySort;
mySort = new SortBy();
Array.Sort(mas, mySort);

Автор: Sash_79 11.11.2007, 18:43
thomas, исправил, но компилятор выдает ту же ошибку

Автор: Magnetic 11.11.2007, 19:14
Почему закомментировано включение //using System.Collections; ?
Интерфейс IComparer находится в пространстве имен System.Collections, его не нужно объявлять как пользовательский. Думаю, ошибка из-за этого. Попробуйте раскомментировать включение пространства имен и уберите описание интерфейса IComparer. У меня код с такими поправками работает.

Автор: 1stain 11.11.2007, 19:32
ты ж здесь
Код

 int IComparer.Compare(object m1, object m2)
        {
          ...

осуществляешь только явную (explicit) реализацию интерфейса IComparer, следовательно в методе Sort, тебе тоже надо привести класс SortBy к интерфейсу IComparer
Код

Array.Sort(mas, new SortBy() as IComparer);


з.ы. Извеняюсь, фигню сморозил...

ученье конечно свет, но не стоит привыкать писать свои варианты того, что есть в библиотеке классов. 

Автор: Sash_79 11.11.2007, 21:06
[/B],Magnetic, если я уберу описание интерфейса Comparer, то программа будет сортировать массив только по именам, а по идентификаторам нет

Добавлено через 3 минуты и 19 секунд
1stain, компилятор всё равно требует чтоб второй параметр Array.Sort() был массивом)

Автор: 1stain 11.11.2007, 21:46
Sash_79, интересно, ты сам дома учишь шарп по троелсену, или еще ходишь куда-то на занятия?
если первое, то внимательнее читай книги и доки. Если второе - то что у тебя там за препод?
интерфейс IComparer уже реализован в пространстве System.Collections. Как раз это тебе пытаецца объяснить 
Magnetic. И реализован намного более опытными людьми. Вот его и юзай.
Кроме того, позволю себе дать пару советов по синтаксису: пространства имен, классы и интерфейсы называй с большой буквы. прменьше используй public поля, а юзай свойства.
я бы сделал примерно так (тут я использую дженерики - если пока не знаешь, что это такое - не страшно)
Код

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ConsoleApplication1
{
    class ConsoleApplication1
    {
        static void Main(string[] args)
        {
            Car[] cars = new Car[] { new Car(3, "Lada"), new Car(2, "Kamaz"), new Car(1, "AutoZaz") };

            Console.WriteLine("Cars array before custom sorting");
            foreach (Car car in cars)
                Console.WriteLine(car.ToString());

            Array.Sort(cars, Car.ByNameCarComparerClass.Instance);

            Console.WriteLine("Cars array after custom sorting");
            foreach (Car car in cars)
                Console.WriteLine(car.ToString());
        }
    }

    public class Car : IComparable
    {
        #region Fields & Propertyes
        private int _id;
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }

        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        } 
        #endregion

        #region .Ctors
        public Car()
        {}

        public Car(int id)
            :this(id, String.Empty)
        {}

        public Car(int id, string name)
        {
            this._id = id;
            this._name = name;
        } 
        #endregion

        #region Public Methods
        public override string ToString()
        {
            return String.Format("Car ID={0,-5} Name={1}", this.Id, this.Name);
        } 
        #endregion

        #region IComparable Members
        public int CompareTo(object obj)
        {
            Car _car = obj as Car;
            if (_car == null)
                throw new ArgumentException("Compared object mast be a Car type");
            return this.Id.CompareTo(_car.Id);
        }
        #endregion

        #region Nested Custom Comparer
        public class ByNameCarComparerClass : IComparer<Car>
        {
            private static ByNameCarComparerClass _instance;
            public static ByNameCarComparerClass Instance
            {
                get
                {
                    if (_instance == null)
                        _instance = new ByNameCarComparerClass();
                    return _instance;
                }
            }

            #region IComparer<Car> Members
            public int Compare(Car x, Car y)
            {
                return StringComparer.InvariantCultureIgnoreCase.Compare(x, y);
            }
            #endregion
        }
        #endregion
    }
}

Автор: Sash_79 12.11.2007, 13:20
1stain, Спасибо за советsmile Учу сам, скоро просто на нем нужно базу будет писать;)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)