Читать «C# 4.0: полное руководство» онлайн - страница 635
Герберт Шилдт
// Пример сохранения объектов класса Inventory в
// обобщенной коллекции класса List<T>.
using System;
using System.Collections.Generic;
class Inventory {
string name; double cost; int onhand;
public Inventory(string n, double c, int h) {
name = n;
cost = c;
onhand = h;
}
public override string ToString() {
return
String.Format("{0,-10}Стоимость: {1,6:C} Наличие: {2}",
name, cost, onhand);
}
}
class TypeSafelnventoryList {
static void Main() {
List<Inventory> inv = new List<Inventory>();
// Добавить элементы в список.
inv.Add(new Inventory("Кусачки", 5.95, 3);)
inv.Add(new Inventory("Отвертки", 8.29, 2));
inv.Add(new Inventory("Молотки", 3.50, 4));
inv.Add(new Inventory("Дрели", 19.88, 8));
Console.WriteLine("Перечень товарных запасов:");
foreach (Inventory i in inv) {
Console.WriteLine(" " + i);
}
}
}
Данный пример отличается от предыдущего лишь передачей типа Inventory
в качестве аргумента типа конструктору класса List<T>
. А в остальном оба примера рассматриваемой здесь программы практически одинаковы. Это, по существу, означает, что для применения обобщенной коллекции не требуется никаких особых усилий, но при сохранении в такой коллекции объекта конкретного типа строго соблюдается типовая безопасность.
Тем не менее для обоих примеров рассматриваемой здесь программы характерна еще одна особенность: они довольно кратки. Если учесть, что для организации динамического массива, где можно хранить, извлекать и обрабатывать данные товарных запасов, потребуется не менее 40 строк кода, то преимущества коллекций сразу же становятся очевидными. Нетрудно догадаться, что рассматриваемая здесь программа получится длиннее в несколько раз, если попытаться закодировать все эти функции коллекции вручную. Коллекции предлагают готовые решения самых разных задач программирования, и поэтому их следует использовать при всяком удобном случае.
У рассматриваемой здесь программы имеется все же один не совсем очевидный недостаток: коллекция не подлежит сортировке. Дело в том, что в классах ArrayList
и List<T>
отсутствуют средства для сравнения двух объектов типа Inventory
. Но из этого положения имеются два выхода. Во-первых, в классе Inventory
можно реализовать интерфейс IComparable
, в котором определяется метод сравнения объектов данного класса. И во-вторых, для целей сравнения можно указать объект типа IComparer
. Оба подхода рассматриваются далее по очереди.
Реализация интерфейса IComparable
Если требуется отсортировать коллекцию, состоящую из объектов определяемого пользователем класса, при условии, что они не сохраняются в коллекции класса SortedList
, где элементы располагаются в отсортированном порядке, то в такой коллекции должен быть известен способ сортировки содержащихся в ней объектов. С этой целью можно, в частности, реализовать интерфейс IComparable для объектов сохраняемого типа. Интерфейс IComparable
доступен в двух формах: обобщенной и необобщенной. Несмотря на сходство применения обеих форм данного интерфейса, между ними имеются некоторые, хотя и небольшие, отличия, рассматриваемые ниже.