| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > .NET для новичков > Сортировка объеков |
| Автор: Лена 24.10.2007, 17:43 | ||
| Допустим есть массив пользовательских объектов: //в Main Car[]myAutos = new Car[5]; myAutos[0] = new Car("Rusty", 80,1); myAutos[1] = new Car("mary", 40,234); //и т.д. Чтобы была возможность отсортировать методом Array.Sort(myAutos); надо добавить в класс Сar поддрежку интрефейса IComparable:
После такого объявления можно использовать Array.Sort(myAutos); Объсните почему в классе Car надо писать так: int IComparable.CompareTo(oblect obj)? Можно ли заменить на: public int CompareTo(oblect obj) ??? |
| Автор: Лена 24.10.2007, 18:20 | ||
| Про вовращаемое значение int я поняла и исправила, но вы уже ответили. Тогда такой вопрос: Например есть интрефейс ICloneable он имеет метод Сlone. Вот есть такой рабочий код:
Почему же в этом случае автор не написал: object ICloneable.Clone() ? Все таки будет работать сортировка в первом коде если класс Car будет иметь один метод public int CompareTo(oblect obj) и унаследован от IComparable? |
| Автор: OLEG_NET 24.10.2007, 18:33 |
| потому что был создан один метод Clone и он принадлежит интерфейсу ,если ты захочешь чтобы у тебя этот метод мог наследоваться в других классах ,ты должна будешь написать свой метод,так как по-умолчанию методы интерфейса невиртуальные,и тогда будешь ставить перед Clone имя интерфейса,а еще это нужно для того чтобы явно вызывать объект интерфейса |
| Автор: Лена 24.10.2007, 18:55 |
| Из того, что я поняла имя интрефейса используется при нотации метода (например, int IComparable.CompareTo(oblect obj)) только для того, чтобы в коде Main можно было вызвать такой метод только через интрефейсную ссылку. Также удобно использовать эту натацию при множественном наследовании интрефейсов с одинаковыми именами у методов, чтобы они не перекрывали друг друга. Делаю ли я правильный вывод?: Сортировка в первом коде будет работать и в случае такого обявления int IComparable.CompareTo(oblect obj) и в случае если это объявление будет заменено на public int CompareTo(oblect obj). Ошибки не будет. |
| Автор: OLEG_NET 24.10.2007, 20:54 |
| Вывод правильный! |
| Автор: kurzon 24.10.2007, 21:58 | ||
|
| Автор: tol05 24.10.2007, 23:44 | ||||
kurzon ударил кодом по балаболам
не только поэтому. То, что можно вызывать из Main интерфейсную ссылку - это следствие. А причина - в том, что сами библиотеки .Net (стандартные) построены через использование указателей на интерфейсы. Это удобно с точки зрения полиморфизма. Это позволяет избавится от boxing\unboxing value types - если эти типы реализуют интерфейсы.. Это обеспечивает защищенность типа, мы имеем ссылку на интерфейс - значит можем вызывать только члены интерфейса, а их немного, их тип и кол-во постоянны и не не зависят от типа, реализующего интерфейс.
ошибки не будет, т.к. метод Sort требует параметр типа IComparer. Получив параметр типа Car, CLR попытается привести его к IComparer и это получится. Но это - плохой стиль, в принципе. Что такое типозащищенность? Ты можешь передать в Sort и не Сar, а что угодно, под видом object. Компилятор ошибки не заметит. Но во время выполнения, когда этот obj будет приводиться к IComparer и окажется, что этот obj не реализует интерфейса - ты получишь run time error. |
| Автор: Лена 25.10.2007, 09:56 | ||||||
| Спасибо, в общих чертах понятно: надо всегда в производном классе реализовывать интрефейсные методы через полное имя для надежности (int IComparable.CompareTo(oblect obj)). Код автора в книге:
Лучше так реализовывать:
Оба подхода правильные, только второй ограничивает доступ. Можно получить доступ только через интерфейсную ссылку. Нет у меня глубоко понимание полезности интрефейсов после С++. Можно же было просто абстракные классы с абстакными методами делать и их наследовать и реализовывать в производных. Туман. P.S. Новая идея реализвать класс Car сразу двумя методами:
|
| Автор: tol05 25.10.2007, 11:24 | ||
| Нормальная идея. Когда требуется безопасный CompareTo, но с параметром object - через IComparable.CompareTo Когда работа только с Car - через
кстати, зачем код дублировать? В IComparable.CompareTo() нужно CompareTo(Car car) вызывать (раз уж приводишь объект к Car). Если что-то изменится в алгоритме сравнения, то в двух местах менять не прийдется. |
| Автор: VisualProgrammerNET 26.10.2007, 12:31 |
| К слову, какой алгоритм сортировки используется стандартным дотнетовским Sort()? |
| Автор: Zapozidon 26.10.2007, 12:39 | ||
MSDN про Sort:
Другие наверняка тоже. |
| Автор: VisualProgrammerNET 26.10.2007, 12:50 |
| Да уж, метод Хоара особо быстрым не назовёшь... Надо будет учесть =) |