В списке товаров могут быть представлены товары подлежащие реализации (цена их известна), а также товары, которые только планируют завезти (цена их реализации пока под вопросом). Так тип decimal не является ссылочным, то значение типа null использовать нельзя.
Реализация (С# 1). Рекомендации к решению задачи
A. Создать оболочку ссылочного типа вокруг типа decimal.
B. Создать отдельный логический флаг, указывающий, известна ли цена (bool isPriceKnown)
C. Использовать для неизвестной цены значение 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) Возможность создания необязательных параметров
Пример 5 . Язык интегрированных запросов LINQ (с версии C#3)
Задача языка LINQ – облегчить написание запросов для нескольких источников данных. По синтаксису этот язык близок к SQL.
Реализация (С# 3). Фильтрация коллекции
Помимо запросов используется неявно типизированная локальная переменная.
static void Main(string[] args)
{
List<Product> list = Product.GetSampleProducts();
list.ForEach(Console.WriteLine);
Console.WriteLine();
var filtered = from Product p in list
where p.Price > 10
select p;
foreach (Product product in filtered)
{
Console.WriteLine(product);
}
Console.Read();
}
Реализация (С# 4). Запросы XML
using System.Xml;
using System.Xml.Linq;
<?xml version="1.0" encoding="utf-8" ?>
<Data>
<Products>
<Product Name ="West Side Story" Price ="9.99 "/>
<Product Name ="Assasins" Price ="14.99 "/>
<Product Name ="Frogs" Price ="13.99 "/>
<Product Name ="Sweeney Todd" Price ="10.99 "/>
</Products>
</Data>
XDocument doc = XDocument.Load("data.xml");
var filtered = from p in doc.Descendants("Product")
where (decimal)p.Attribute("Price") > 10
select new
{
ProductName = (string)p.Attribute(“Name”);
};
foreach (var v in filtered)
{
Console.WriteLine(v.ProductName);
}
Пример 6. Модель COM и динамическая типизация
Главной идей версии С#4 является тема совместимости. Это подразумевает работу как со старой технологией COM, так и с элементами динамических языков, выполняющихся в исполняющей среде динамического языка (Dynamic Language Runtime – DLR)
Задача 1. Экспорт списка продуктов в электронную таблицу Excel.
Необходимо добавить ссылку проекта на Microsoft.CSharp для обеспечения внедрения в основной код соответствующих частей основной сборки взаимодействия (Primary Interop Assembly – PIA). Более того в свойствах ссылки на пространство имен Excel свойство Imbeded Interop Type необходимо установить в значение true. Типы пространства имен Interop становятся в этом случае динамическими и не требуют явного преобразования.
using Microsoft.Office.Interop.Excel;
var app = new Application{Visible = false};
Workbook workbook = app.Workbooks.Add();
Worksheet worksheet = (Worksheet)app.ActiveSheet;
int row = 1;
foreach (var product in Product.GetSampleProducts().Where(p => p.Price != null))