Пример 2. Сортировка и фильтрация
Реализация (С# 4). Именованные аргументы
За базовую возьмем версию C#1 (для свойств и конструкторов). Более однозначно указывается, у что разрабатываемого типа данных поля могут быть изменены только внутренне (readonly).
class Product
{
readonly string name;
public string Name { get { return name; } }
readonly decimal price;
public decimal Price { get { return price; } }
public Product(string name, decimal price)
{
this.name = name;
this.price = price;
}
public static List<Product> GetSampleProducts()
{
return new List<Product>{
new Product (name: "West Side Story", price: 9.99m),
new Product (name: "Assasins", price: 14.99m),
new Product (name: "Frogs1", price: 13.99m),
new Product (name: "Sweeney Todd",price: 10.99m)
};
}
Эволюция:
1. Свойства только для чтения; слабо типизированные коллекции
2. Закрытые методы установки значения свойств; строго типизированные коллекции
3. Автоматически реализуемые свойства; улучшенная инициализация коллекций и объектов
4. Именованные аргументы для конструктора и вызовов методов
Рассматриваем набор продуктов. Задача состоит в том, чтобы отсортировать их по имени и найти самые дорогие товары.
|
|
Используем метод ArrayList.Sort, который обеспечивает реализацию интерфейса ICompare.
Семантическая и синтаксическая конструкция в коде программы, используемая для специфицирования услуг, предоставляемых классом или компонентом.
Тип Product может реализовывать интерфейс IComparable, но в этом случае можно будет указать только один порядок сортировки. Поэтому отдельно будет записан интерфейс IComparer, который будет применятся для сортировки.
using System.Collections;
class ProductNameComparer:IComparer // интерфейс
{ //обязательно должен содержатьфункцию сравнения
public int Compare(object x, object y)
{
Product first = (Product)x;
Product second = (Product)y;
return first.Name.CompareTo(second.Name);
}
}
static void Main (string[] args)
{
ArrayList list = Product.GetSampleProducts();
foreach (Product product in list)
Console.WriteLine(product.ToString());
Console.WriteLine();
list.Sort(new ProductNameComparer());
foreach (Product product in list)
Console.WriteLine(product.ToString());
Console.Read();
}
Ограничения/недостатки:
1. Необходимо определить дополнительный тип, помогающий в сортировке.
2. В методе Compare вынуждены использовать приведение типов (cast) при преобразовании типа object в Product.
3. В переборе foreach также присутствует неявное преобразование типов, что при такой организации списка может привести к ошибкам.
Реализация (С# 2). Сортировка List<Product> с использованием интерфейса IComparer <Product>
using System.Collections.Generic;
class ProductNameComparer:IComparer<Product>
{
public int Compare(Product x, Product y)
{
return x.Name.CompareTo(y.Name);
}
}
static void Main(string[] args)
{
List<Product> list = Product.GetSampleProducts();
foreach (Product product in list)
Console.WriteLine(product.ToString());
Console.WriteLine();
list.Sort(new ProductNameComparer());
foreach (Product product in list)
Console.WriteLine(product.ToString());
Console.Read();
}
Код для компаратора упрощен. В принципе его можно заменить анонимным методом.
|
|
list.Sort(delegate(Product x, Product y)
{ return x.Name.CompareTo(y.Name);}
);
Реализация (С# 3). Сортировка списка с использованием делегата Comparison <Product>
Создается экземпляр делегата, который передается методу Sort для выполнения сравнения.
static void Main(string[] args)
{
List<Product> list = Product.GetSampleProducts();
foreach (Product product in list)
Console.WriteLine(product.ToString());
Console.WriteLine();
list.Sort(delegate(Product x, Product y)
{
return x.Name.CompareTo(y.Name);
}
);
foreach (Product product in list)
Console.WriteLine(product.ToString());
Console.Read();
}
Реализация (С# 3 V2). Сортировка списка с использованием делегата Comparison <Product> из лямбда-выражения
Создание делегата с использованием особого вида синтаксиса (лямбда-выражения)
static void Main(string[] args)
{
List<Product> list = Product.GetSampleProducts();
foreach (Product product in list)
Console.WriteLine(product.ToString());
Console.WriteLine();
list.Sort((x,y)=>x.Name.CompareTo(y.Name));
foreach (Product product in list)
Console.WriteLine(product.ToString());
Console.Read();
}