Страница 479 из 502
<b> }</b>
<b>}</b>
<b>class Inventory {</b>
<b> public string name;</b>
<b> double cost;</b>
<b> int onhand;</b>
<b> public Inventory(string n, double c, int h) {</b>
<b> name = n;</b>
<b> cost = c;</b>
<b> onhand = h;</b>
<b> }</b>
<b> public override string ToString() {</b>
<b> return</b>
<b> String.Format("{0,-10} Цена: {1,6:С} В наличии: {2}",</b>
<b> name, cost, onhand);</b>
<b> }</b>
<b>}</b>
<b>class GenericIComparerDemo {</b>
<b> static void Main() {</b>
<b> CompInv<Inventory> comp = new CompInv<Inventory>();</b>
<b> List<Inventory> inv = new List<Inventory>();</b>
<b> // Добавить элементы в список.</b>
<b> inv.Add(new Inventory("Кусачки", 5.95, 3));</b>
<b> inv.Add(new Inventory("Отвертки", 8.29, 2));</b>
<b> inv.Add(new Inventory("Молотки", 3.50, 4));</b>
<b> inv.Add(new Inventory("Дрели", 19.88, 8));</b>
<b> Console.WriteLine("Перечень товарных запасов до сортировки:");</b>
<b> foreach (Inventory i in inv) {</b>
<b> Console.WriteLine(" " + i);</b>
<b> }</b>
<b> Console.WriteLine();</b>
<b> // Отсортировать список, используя интерфейс IComparer.</b>
<b> inv.Sort(comp);</b>
<b> Console.WriteLine("Перечень товарных запасов после сортировки:");</b>
<b> foreach (Inventory i in inv) {</b>
<b> Console.WriteLine(" " + i);</b>
<b> }</b>
<b> }</b>
<b>}</b>
Применение класса StringComparer
В простых примерах из этой главы указывать явно способ сравнения символьных строк совсем не обязательно. Но это может потребоваться в тех случаях, когда строки сохраняются в отсортированной коллекции или когда строки ищутся либо сортируются в коллекции. Так, если строки должны быть отсортированы с учетом настроек одной культурной среды, а затем их приходится искать с учетом настроек другой культурной среды, то во избежание ошибок, вероятнее всего, потребуется указать способ сравнения символьных строк. Аналогичная ситуация возникает и при хешировании коллекции. Для подобных (и других) случаев в конструкторах классов некоторых коллекций предусмотрена поддержка параметра типа IComparer. С целью явно указать способ сравнения символьных строк этому параметру передается в качестве аргумента экземпляр объекта класса StringComparer.
Класс StringComparer был подробно описан в главе 21 при рассмотрении вопросов сортировки и поиска в массивах. В этом классе реализуются интерфейсы IComparer, IComparer<String>, IEqualityComparer, а также IEqualityComparer<String>. Следовательно, экземпляр объекта типа StringComparer может быть передан параметру типа IComparer в качестве аргумента. В классе StringComparer определяется несколько доступных только для чтения свойств, возвращающих экземпляр объекта типа StringComparer, который поддерживает различные способы сравнения символьных строк. Как пояснялось в главе 21, к числу этих свойств относятся следующие: CurrentCulture, CurrentCulturelgnoreCase, InvariantCulture, InvariantCulturelgnoreCase, Ordinal, а также OrdinallgnoreCase. Все эти свойства можно использовать для явного указания способа сравнения символьных строк.
В качестве примера ниже показано, как коллекция типа SortedList<TKey, TValue> конструируется для хранения символьных строк, ключи которых сравниваются порядковым способом.
<b>SortedList<string, int> users =</b>
<b> new SortedList<string, int>(StringComparer.Ordinal);</b>
Доступ к коллекции с помощью перечислителя
К элементам коллекции нередко приходится обращаться циклически, например, для отображения каждого элемента коллекции. С этой целью можно, с одной стороны, организовать цикл foreach, как было показано в приведенных выше примерах, а с другой — воспользоваться перечислителем. Перечислитель — это объект, который реализует необобщенный интерфейс IEnumerator или обобщенный интерфейс IEnumerator<T>.
В интерфейсе IEnumerator определяется одно свойство, Current, необобщенная форма которого приведена ниже.
<b>object Current { get; }</b>
А в интерфейсе IEnumerator<T> объявляется следующая обобщенная форма свойства Current.