Следует отметить, что с помощью пользовательских статических свойств вы можете помочь пользователю объекта отсортировать типы Car по заданному элементу данных. Предположим, что в класс Car добавлено статическое свойство SortByPetName, доступное только для чтения и возвращающее экземпляр объекта, реализующего интерфейс IComparer (в данном случае это PetNameComparer).
// Здесь обеспечивается поддержка пользовательского свойства для
// возвращения "правильного" интерфейса IComparer.
public class Car: IComparable
…
// Свойство, возвращающее компаратор SortByPetName
public static IComparer SortByPetName { get { return (IComparer)new PetNameComparer; } }
}
В программном коде пользователя объекта теперь можно выполнить сортировку по названию, используя ассоциированное свойство без какого бы то ни было "упоминания" специального типа класса PetNameComparer:
// Сортировка по имени становится немного проще.
Array.Sort(myAutos, Car.SortByPetName
Исходный код.
Проект ComparableCar размещен в подкаталоге, соответствующем главе 7.Теперь вы должны понимать не только то, как определяются и реализуются типы интерфейса, но и то, в чем их польза. Будьте уверены, интерфейсы можно обнаружить в любом из главных пространств имен .NET и в завершение этой главы мы рассмотрим примеры интерфейсов (и базовых классов) из пространства имен System.Collections.
Интерфейсы из пространства имен System.Collections
В качестве самого примитивного контейнера может выступать тип System.Array. В главе 3 было показано, что класс System.Array предлагает целый ряд соответствующих возможностей (таких, как инвертирование, сортировка, очистка и перечисление). Но класс Array имеет свои ограничения, и наиболее важным из них является невозможность динамического переопределения размеров при добавлении и удалении элементов. Если для хранения типов необходим более "гибкий" контейнер, лучше использовать типы, определенные в пространстве имен System.Collections (или, в соответствии с рекомендациями главы 10, из пространства имен System.Collections.Generic).
Пространство имен System.Collections определяет целый ряд интерфейсов (и некоторые из них уже использовались в примерах этой главы). Как правило, коллекции классов реализует эти интерфейсы для того, чтобы обеспечить доступ к своему содержимому. В табл. 7.2. приводятся описания основных интерфейсов, относящихся к коллекциям.
Таблица 7.2. Интерфейсы System.Collections
Интерфейс | Описание |
---|---|
ICollection | Определяет общие характеристики (такие, как защищенность счетчиков и цепочек) для типа коллекции |
IComparer | Позволяет сравнение двух объектов |
IDictionary | Позволяет объекту представить его содержимое с помощью пар имен и значений |
IDictionaryEditor | Перечисляет содержимое типа, поддерживающего IDictionary |
IEnumerable | Возвращает интерфейс IEnumerator для данного объекта |
IEnumerator | Обеспечивает общую поддержку перечисления подтипов с помощью foreach |
IHashCodeProvider | Возвращает хеш-код для реализующего типа, используя настраиваемый механизм хеширования |
IKeyComparer | Этот интерфейс является новым в .NET 2.0). Объединяет функциональные возможности IComparer и IHashCodeProvider, чтобы обеспечить сравнение объектов по их хеш-кодам (если объекты (равны, то они должны возвращать одинаковые хеш-коды) |
IList | Обеспечивает возможность добавления, удаления и индексирования элементов в списке объектов. Кроме того, с помощью членов этого интерфейса можно выяснить, является ли данный тип-контейнер коллекции доступным только для чтения, и имеет ли он фиксированный размер |