Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Доп главы ПРГ Лекция 1.docx
Скачиваний:
9
Добавлен:
11.06.2015
Размер:
46.02 Кб
Скачать

Пример 3 . Запрос коллекций

Задача: найти все элементы списка, соответствующие заданным критериям (цена товара превышает 10 $)

Реализация (С# 1). Перебор, проверка, отображение

Перебор каждого элемента, его проверка и отображение

using System.Collections;

static void Main(string[] args)

{

ArrayList list = Product.GetSampleProducts();

foreach (Product product in list)

Console.WriteLine(product.ToString());

Console.WriteLine();

foreach (Product product in list)

if (product.Price > 10m)

{

Console.WriteLine(product.ToString());

}

Console.Read();

}

Ограничения/недостатки:

Из-за вложения инструкций друг в друга появляется зависимость между задачами такими как перебор, проверка, вывод.

Реализация (С# 2). Разделение проверки и отображения.

Создание делегатов testиprint, которые впоследствии передаются в соответствующий метод

using System.Collections.Generic;

static void Main(string[] args)

{

List<Product> list = Product.GetSampleProducts();

Action<Product> print = Console.WriteLine; // преобразование группы методов (технология v2)

list.ForEach(print);

Console.WriteLine();

Predicate<Product> test = delegate(Product p) { return p.Price > 10m; };

List<Product> matches = list.FindAll(test);

matches.ForEach(print);

Console.Read();

}

Упрощенная запись, абсолютно аналогичная версии выше:

static void Main(string[] args)

{

List<Product> list = Product.GetSampleProducts();

list.ForEach(Console.WriteLine);

Console.WriteLine();

list.FindAll(delegate(Product p) { return p.Price > 10m; }).ForEach(Console.WriteLine);

Console.Read();

}

Реализация (С# 3). Проверка при помощи лямбра-выражения

static void Main(string[] args)

{

List<Product> list = Product.GetSampleProducts();

list.ForEach(Console.WriteLine);

Console.WriteLine();

foreach (Product product in list.Where(p => p.Price > 10))

{

Console.WriteLine(product);

}

Console.Read();

}

Эволюция:

  1. Жесткая связь между условием и действием

  2. Условие отдельно от действия; анонимные методы упрощают делегаты

  3. Лямбда-выражение упрощает условие для чтения

Пример 4 . Обработка отсутствия данных

В списке товаров могут быть представлены товары подлежащие реализации (цена их известна), а также товары, которые только планируют завезти (цена их реализации пока под вопросом). Так тип decimalне является ссылочным, то значение типаnullиспользовать нельзя.

Реализация (С# 1). Рекомендации к решению задачи

  1. Создать оболочку ссылочного типа вокруг типа decimal.

  2. Создать отдельный логический флаг, указывающий, известна ли цена (bool isPriceKnown)

  3. Использовать для неизвестной цены значение decimal.MinValue

Реализация (С# 2). Структура Nullable<T>.

decimal? price;

public decimal? Price

{

get { return price; }

private set { price = value; }

}

public Product(string name, decimal? price)

{

Name = name;

Price = price;

}

Реализация (С# 3). Отображение продуктов с неизвестной ценой

static void Main(string[] args)

{

List<Product> list = Product.GetSampleProducts();

list.ForEach(Console.WriteLine);

Console.WriteLine();

foreach (Product product in list.Where(p => p.Price ==null))

{

Console.WriteLine(product);

}

Console.Read();

}

Реализация (С# 4). Необязательные параметры и значения по умолчанию

public Product(string name, decimal? price = null)

{

this.name = name;

this.price = price;

}

Product p = new Product(“Unreleased product”);

Эволюция:

  1. (C#1)Выбор между дополнительной работой по поддержке флага, изменением семантики ссылочного типа или применением специального значения

  2. (С#2/3) Типы данных, допускающие значение null

  3. (C#4)Возможность создания необязательных параметров