Застосування лямбда-виразів в Visual C # (Sharp)

Використання лямбда-виразів не полегшить вашу роботу з програмування І, безсумнівно, спочатку у вас будуть проблеми з їх розумінням Але коли ви розберетеся з ними, то вони зроблять рішення певного класу проблем трівльним

Ідея лямбда-виразів полягає в відкладення виконання на пізній час Вони ніби кажуть: Коли будемо виконувати операцію х, тоді також виконаємо операцію у

У попередньому розділі ми розглянули один з сценаріїв використання лямбдираженій Щоб продемонструвати інше їх застосування, розглянемо прлему іншого роду Візьмемо просту електронну таблицю, в якій потрібно перчітать формули в осередках, не порушуючи стан осередків Відповідні осередку показані на рис 91

Рис 91 Осередки електронної таблиці

Наша електронна таблиця має девять осередків, три з яких містять значення Осередки А2 і Bi містять значення, а осередок сз – формулу, яка підсумовує лю перших двох осередків Результати осередку сз множаться на 2 і поміщаються в комірку С2 Все це стандартні операції з електронною таблицею Тепер рамотрім вихідний код для виконання обчислень у таблиці Подумайте немно, як це зробити, перш ніж продовжувати читати далі

Проблема з цим завданням полягає в тому, що ми не можемо виконати обробку від одного кута до іншого Уявіть, що осередок можна представити таким інтерфейсом, що містить один метод Execute ()

interface ICell { void Execute()

}

Метод Execute про можна розглядати як чарівний, т к він сам знає, що робити з осередком Тоді всю таблицю можна наступній колекцією:

IListcIListcICell» spreadsheet

Колекція всередині оголошення колекції створює двовимірний список осередків Дане оголошення є прикладом електронної таблиці з динамічними розмірами Для порівняння, розглянемо наступне оголошення масиву електронної таблиці постійних розмірів:

ICell[,]  spreadsheet

Як бачимо, електронну таблицю можна оголосити декількома способами Для даного прикладу ми будемо користуватися таблицею, оголошеної як колекція колекцій

Для обробки таблиці створюється цикл foreach, в якому виповнюється метод

ICellExecute():

foreach (IList&ltICell&gt rows in spreadsheet) { foreach (ICell cell in rows) {

cellExecuted

}

}

Алгоритм проходить в циклі по колекціях і обробляє містяться в них осередки Але такий підхід буде неправильним, тому що в ньому осередок С2 буде обротана раніше, ніж осередок сз Але логіка нашої електронної таблиці зворотна даному напрямку обробки, тобто осередок сз повинна оброблятися перед осередком С2

Щоб алгоритм працював належним чином, структуру осередків необхідно реоргановать таким чином, щоб осередок сз оброблялася перед осередком С2 Нам нбходімо створити іншу структуру, що включає ієрархію обробки

Іншим підходом до організації електронної таблиці буде використання лямбда-виразів Розглянемо наступне оголошення електронної таблиці:

class Spreadsheet {

public Func&ltobject&gt[,] Cells

public object,] State

public Spreadsheet() {

Cells = new Func&ltobject&gt[10, 10] State = new objecttlO, 10]

&gt&nbsp

public void Execute() {

for (int col = 0 col &lt CellsGetLength(l) col++) { for (int row = 0 row &lt CellsGetLength(O) row++) {

if (Cells[col, row] = null) { State[col, row] = Cellsfcol, row]()

&gt&nbsp

}

}

}

}

Дана таблиця має два члени даних – cell s і state Член даних Cell s яяется двовимірним масивом лямбда-виразів, які повертають обєкт Кожне лямбда-вираз буде містити якийсь виконуваний код Член даних stat e містить результати виконання і надається користувачеві

Значення осередкам присвоюються за допомогою наступного коду:

static class CellFactories {

public static Func&ltobject&gtDoAdd(Func&ltobject&gt celll,

Func&ltobject&gtcell2){ return () =&gt (double)celll() + (double)cell2()

}

public static Func&ltobject&gt DoMultiply(Func&ltobject&gt celll,

Func&ltobject&gt cell2) { return () =&gt (double)celll() * (doublecell2()

}

public static Func&ltobject&gt Static(object value) { return () =&gt value

}

}

Клас з CellFactories Містить три методу: DoAdd (), DoMultiply () І Static про, корие підсумовують, множать і обчислюють статичне значення в певній клітинці відповідно Розглянемо реалізацію методу DoAdd () Тут лямбдираженіе використовує два інших лямбда-вирази, щоб отримати значення для обчислення результату складання

Послідовність виконуваних операцій визначається структурою лямбдираженій Це означає, що якщо першими запитуються результати для комірки С2,

то виконується звернення та обробка осередку сз, в результаті якої витягуються значення комірок А2 І BI Таким чином, усувається можливість неправильного Вісленев осередків Код для обробки електронної таблиці, показаної на рис 91, виглядає таким чином:

Spreadsheet spreadsheet = new Spreadsheet()

spreadsheetCells[1,0] = CellFactoriesStatic(100) spreadsheetCells[0,1] = CellFactoriesStatic(100) spreadsheetCells[1,2] =

CellFactoriesDoAdd(spreadsheetCells[1,0],  spreadsheetCells[0,1]) spreadsheetCells[2,2] =

CellFactoriesDoMultiply(spreadsheetCells[1,2],

CellFactoriesStatic(20))

spreadsheetExecute()

У даному коді, за допомогою фабрик инициализируются базові значення ю о і ЮО Зверніть увагу на формат значень: ЮО, а не просто ю Відсутність десяткового дробу і нуля викликало б помилку перетворення типів Потім випояется операція присвоювання значення осередку cell[1, 2], для чого викликається мето д DoAdd () З осередкам і Cells [1, 0] і Cells [0,1]

Джерело: Гросс К С # 2008: Пер з англ – СПб: БХВ-Петербург, 2009 – 576 е: ил – (Самовчитель)

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*