Знаходження кімнатної угруповання програми управління освітленням в Visual C # (Sharp)

У списку, що містить кілька кімнатних угруповань, нам буде потрібно знайти угруповання, що відповідають певним опису Так як кімнатні групповкі організовані в двонаправлений список, для цього потрібно перевіряти кожен

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

public object FindRoomGrouping(string description) { RoomGrouping curr = _roomGroupingsNext as RoomGrouping while (curr = null) {

if (currDescriptionCompareTo(description) == 0) {

return curr

}

curr = currNext as RoomGrouping

}

return null

}

Даний код циклу схожий на код циклу, розглянутий у розд Збереження коекціі за допомогою повязаного списку раніше в цьому розділі Єдина різниця полягає в тому, що змінна curr має тип RoomGrouping, і т к Next отнітся до типу BaseLinkedList, то потрібно виконати приведення типів Цикл виконується за допомогою оператора while і при кожній ітерації циклу curr Description порівнюється з параметром description Якщо потрібний обкт виявлений, то повертається дескриптор RoomGrouping в іншому випадку воращается значення null

Цей метод використовується таким чином:

object foundHandle = controllerFindRoomGrouping(&quotdescription&quot)

Але звязаний список кімнатних угруповань є колекцією, до якої можна звертатися, як до масиву У мові С # є конструкції, за допомогою корих клас LightingController можна постачити функціональністю масиву, Нива индексатором Далі наводиться код методу класу LightingController, який виконує дану операцію:

public object this[string description] { get {

return FindRoomGrouping(description)

}

}

Індексатор оголошується подібно властивості, за винятком того, що в якості ідентифікатора властивості використовується ключове слово this, після якого слуют увязнені у фігурні дужки параметри масиву Повертаний індеатором тип вказується ідентифікатором перед ключовим словом this У даом прикладі визначена тільки частина get індексатора, тому доступ до нього надається тільки для читання Даний індексатор можна використовувати слующім чином:

object foundHandle = controller[&quotdescription&quot]

Таким чином, за допомогою індексатора можна визначити доступ до масиву допомогою інших, ніж числових, індексів

ПРИМІТКА

Індексатори надають сервісну функціональність, і їх лучш е всього встаять в класи, управляюще е колекціями Клас LightingController, який управляє колекцією кімнатних угруповань, є гарні м кандидатом для постачання я индексатором

Певну кімнатну угруповання можна знайти за допомогою методів або іексатора класу LightingController Але іноді користувачеві потрібно інфоація про всі наявні кімнатних угрупованнях Для цього можна визначити числовий індексатор і обробити в циклі окремі елементи Відповідний код буде виглядати так:

public string this[int index]  { get { }

}

Попередній приклад індексатора і метод FindRoomGrouping () повертають десіптор обєкта Але даний приклад індексатора повертає рядок Для обробки в циклі кімнатних угруповань нам не потрібен дескриптор, т к ми не знаємо, що представляє даний дескриптор Якщо викликати метод FindRoomGrouping () і хвилю пошук на основі опису, то повернений дескриптор матиме пекрестную посилання з описом При обробці елементів у циклі за допомогою члового індексатора повернений дескриптор обєкта не має для нас ніякого значення, будучи всього лише повязаними з певним індексом Але що нам дійсно потрібно знати, так це які є описи, і тому числовий індексатор повертає рядок з перехресним посиланням на опис кімнатної угруповання

ПРИМІТКА

Ті п може мати кілька визначень індексаторів, але всі вони повинн и мати різні параметр и масиву

Припустимо, що у нас є числовий індексатор Для обробки в циклі відділах кімнатних угруповань ми можемо використовувати такий код:

for (int cl = 0 cl &lt controllerLength cl ++) { string description = controller[cl]

}

У той час як даний код циклу є прийнятним, в ньому необхідно добити властивість Length в клас LightingController Кращим підходом буде іользованіе ключового слова foreach таким чином:

foreach (string description in controllerRoomGroupinglterator()) {

/ / Виконується небудь операція з описом

}

Даний код краще, т к оператор foreach має більш простий сінтаіс Не грає ролі, що ми втратили інформацію про те, яке зміщення відноситься до якого опису, т к ця інформація все одно не представляє ніякої цінності Не забувайте, що ми маємо справу зі звязаним списком, елементи в кором можуть розміщуватися в будь-якому порядку Тому числовий ідентифікатор в даному випадку абсолютно даремний Єдиним надійним способом знайти кімнатну угруповання є наявність її опису або специфічного для коекціі індексу

ПРИМІТКА

Якщо тільки ви повністю не впевнені в тому, що елементи маніпульованого Коллея не переміщаються з одного місця на інше, використання індексу в якості унікального опису обєкта може бути небезпечним і потенційно спотворити відбудуться додатки У цій главі я вже показав два інших способи звернення до опреденному обєкту, а саме – дескриптор і індексатор

Так як клас LightingController не має вбудованої функціональності foreach, необхідно вдатися до допомоги ключового слова yield, щоб добити її Далі наводиться код для реалізації циклу за допомогою ключового слова yield (На самому початку файлу LightingController необхідно додати оператор using System Collections, щоб отримати доступ До інтерфейсу I Enumerable) Public IEnumerable RoomGroupinglterator () {

RoomGrouping curr = _roomGroupingsNext as RoomGrouping while (curr = null) {

yield return currDescription

curr = currNext as RoomGrouping

}

}

У ітератори за допомогою змінної curr створюється інший цикл for, але для нас важливим є код, виділений жирним шрифтом Тут ключове слово yield використовується спільно з ключовим словом return Ключове слово return не слід розглядати окремо, як вказує вихід з функції В даному випадку ключові слова yield і return складають одну цільну конструкцію, яка застосовується для передачі повідомлень

Ключове слово yield завжди доставляє розробникам великі труднощі з його розумінням Найкращим способом зрозуміти його буде дослідження, як воно Рота спільно з ключовим словом foreach:

1 Коли код доходить до оператора foreach, встановлюється контекст, в якому елементи колекції обробляються в ітератори Установка контексту полягає в отриманні колекції та виділення місця для окремого елементу

2 Викликається итератор колекції, що для даного прикладу означає виклик мето-

да RoomGroupinglterator ()

3 Метод RoomGroupingiterator () присвоює змінної curr значення, що вказує на перший елемент двонаправленого списку кімнатних угруповань

4 Починається виконання циклу, тривале до тих пір, поки значення

curr не стане рівним нулю

5 Код доходить до комбінації yield return, що означає, що результат після ключового слова return потрібно зберегти в області памяті для окремого елемента, виділеної в кроці 1

6 Код створює ятати, помічаємо останній сповнений оператор в ітероре, і переходить назад до оператора f oreach

7 Оператор foreach продовжує виконання коду, яким у даному прикладі є коментар

/ / Виконується небудь операція з описом

8 Коли оператор foreach приступає до виконання наступної ітерації, ізвлается раніше збережена закладка і здійсняться код, наступний відразу ж після закладки В результаті виповнюється код curr = curr Next as RoomGrouping У методі RoomGroupingiterator ()

9 Виконання ітератора триває, і кроки 4-9 виконуються доти, поки значення curr не стане рівним нулю

10&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Коли значення curr стає рівним нулю, виконання ітератора припиняючи, викликаючи зупинку циклу foreach

Частиною, важко піддається розумінню, є механізм, застосовуваний, коли конструкція yield return викликає припинення виконання з подальшим його відновленням Програмісти не звикли до того, що можна виходити і вхіть в метод і продовжувати виконання Але не забувайте, що це можна робити тільки в контексті комбінації оператора foreach і конструкції yield return Цей механізм, заснований на використанні закладок, непридатний у С # ні в кой іншій ситуації

У цьому прикладі було показано застосування ключового слова yield в циклі, але цикл не є обовязковим Так в наступному фрагменті коду yield іспользтся в колекції з трьох чисел:

public IEnumerable Numberlterator() { yield return 1

yield return 2

yield return 3

}

ВАЖЛИВІСТЬ індексатора і ключове слово YIELD

У прикладі для цієї глави демонструється використання індексаторів і ключового слова yiel d дл я додання типом виду звичайної колекції Використання даного прикладу має певну мету Але гарний це приклад Я намагаюся навчити вас,

як писати програмне забезпечення професійно на високому рівні, тобто наіть вас інженерії розробки ПЗ Уміння працювати зі звязаними списками явлтся частиною цієї інженерії розробки ПЗ, але чи використовуються звязані списки в сьогоднішньому програмуванні Не дуже То чи потрібно сучасним программтам знати про повязані списках Звичайно ж, точно так само як необхідно знати, як виконувати арифметичні операції, хоча для виконання їх ми сьогодні пользуея НЕ олівцем і папером, а калькулятором

Таким чином, якщо приклад ілюструє деякі можливості С #, але в действельності ми навряд чи будемо робити що-небудь подібне показаному в прикладі Пезни Чи ці можливості Так, ці можливості корисні Уявіть, що ви ладі будинок і вам необхідні крокви для даху Щоб прискорити складання крокв і щоб вони були найбільш однакові, ви спочатку робите пристосування для утримування компонентів крокв необхідним чином Дані пристосування не використовуються безпосередньо у будівництві будинку, вони служать лише для ускенія складання елементів його конструкції Подібним чином індексатори і ключі слово yield спрощують і прискорюють розробку класів, відповідних стаартной парадигмі програмування мовою С #

Іноді доводиться створювати конструкційні класи, які не роблять нічого, окрім як забезпечують працездатність інших компонентів, що виконують пезную роботу Ось для створення конструкційних класів нам і знадобляться індеатори, а також ключове слово yield Так що думайте про індексатора і ключовому слові yield як про механізм, який дозволяє множинним елементам виглеть, як колекція С #

Джерело: Гросс К С # 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>

*

*