Программирование >>  Программирование с использованием ajax 

1 ... 121 122 123 [ 124 ] 125 126 127 ... 396


Тогда определение делегата в Connection. cs можно было бы изменить следующим образом:

public delegate void MessageHandler(object source, EventArgs e) ;

Данное приложение работало бы в точности так же, как и раньше, но его функция DisplayMessage () стала бы более разносторонней (по крайней мере, теоретически, поскольку на практике для достижения более высокого качества потребовалось бы больше реализации). Тот же самый обработчик смог бы работать и с другими событиями, такими как Timer. Elapsed, хотя пришлось бы изменить внутренние детали обработчика еще немного, чтобы параметры, отправляемые при генерации данного события, обрабатывались надлежащим образом (приведение их к типу объектов Connection и MessageArrivedEventArgs показанным способом приведет к генерации исключения; вместо этого должна использоваться операция as и выполняться проверка на предмет наличия в них значения null).

Возвращаемые значение и обработчики событий

у всех демонстрировавшихся до сих пор обработчиков событий возвращаемым типом был void. Предоставлять для события возвращаемый тип в принципе допускается, но это чревато возникновением проблем, поскольку каждое взятое событие может приводить к вызову нескольких обработчиков. Если все они возвращают значение, тогда может быть не ясно, какое именно значение было возвращено.

Система справляется с этой проблемой, позволяя получать доступ только к последнему значению, которое было возвращено обработчиком событий. Таковым всегда будет значение, возвращенное обработчиком, который последним подписался на данное событие. Хотя эта функциональность и может оказаться полезной в некоторых ситуациях, все-таки рекомендуется применять обработчики событий с возвращаемым типом void и избегать параметров out.

Анонимные методы

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

Синтаксис, необходимый для создания анонимного метода, выглядит следующим образом:

delegate {параметры) {

Код анонимного метода.

На месте параметры указывается перечень параметров, соответствующих параметрам делегата, экземпляр которого создается, в том виде, в котором они должны использоваться в коде анонимного метода:

delegate (Connection source, MessageArrivedEventArgs e)

Код анонимного метода, соответствующего событию MessageHandler в СЫЗЕхОЗ.

Например, с помощью следующего кода можно было бы полностью пропустить метод Display. DisplayMessage () в СЫЗЕхОЗ:



myConnectionl.MessageArrived +=

delegate(Connection source, MessageArrivedEventArgs e)

Console.WriteLine( Message arrived from: {0} , source.Name); Console.WriteLine( Message Text: {0} , e.Message);

Интересное свойство анонимных методов состоит в том, что они, по сути, являются локальными для того блока кода, в котором содержатся, и имеют доступ ко всем локальным переменным в этой области действия. В случае использования такой переменной она становится внешней (outer). Внешние переменные не уничтожаются при выходе за пределы области действия, как это происходит с другими локальными переменными; вместо этого они продолжают существовать до тех пор, пока не будут уничтожены методы, в которых они используются, что может случаться позже, чем ожидается, и потому обязательно требует внимательного отношения.

Расширение и использование CardLib

Теперь, когда было показано, как определять и использовать события, пришла пора попробовать применить полученные знания на практике в проекте ChlSCardLib. Событие, которое предлагается добавить, будет генерироваться при получении последнего объекта Card в объекте Deck с использованием GetCard и называться LastCardDrawn (Последняя вытянутая карта). Оно будет позволять подписчикам перемешивать колоду автоматически и тем самым сокращать объем подлежащей выполнению клиентом обработки. Делегат, определяемый для этого события (LastCardDrawnHandler), должен поставлять ссылку на объект Deck так, чтобы метод Shuffle О был доступен отовсюду, где бы ни находился обработчик. Это требует добавления в Deck.сS следующего кода:

namespace Chl3CardLib {

public delegate void LastCardDrawnHandler (Deck currentDeck) ;

Код для определения описанного события и его генерации выглядит просто:

public event LastCardDrawnHandler LastCardDrawn;

public Card GetCard(int cardNum) {

if (cardNum >= 0 && cardNum <= 51) {

if ((cardNum = 51) && (LastCardDrawn !=null))

LastCardDrawn(this); return cards[cardNum];

else

throw new CardOutOfRangeException((Cards)cards.Clone 0);

Это и есть весь код, необходимый для добавления собьггия в определение класса Deck.

Клиентское приложение для игры в карты, использующее CardLib

Потратив столько времени на разработку библиотеки CardLib, было бы нелепо не воспользоваться ею. Поэтому напоследок в этом разделе, посвященном дополнительным механизмам ООП в С# и .NET Framework, предлагается немного развлечься



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

Как и в предыдущих главах, сначала необходимо добавить в решение ChlSCardLib клиентское консольное приложение, назвать его ChlSCardClient, добавить в него ссылку на проект Chl3CardLib и сделать его стартовым проектом.

Потом нужно создать в нем новый класс по имени Player, размещаемый в новом файле Player. CS. Этот класс должен содержать приватное поле типа Cards по имени Hand, приватное строковое поле с именем name и два доступных только для чтения свойства Name и PlayHand. Эти свойства будут просто предоставлять доступ к соответствующим приватным полям. Хотя свойство PlayHand и должно быть доступным только для чтения, к возвращаемой им ссылке на поле hand доступ должен быть не только для чтения, но и для записи, чтобы с ее помощью можно было изменять имеющиеся на руках у игрока карты.

Еще необходимо скрыть конструктор по умолчанию, сделав его приватным, и предоставить общедоступный конструктор не по умолчанию, принимающий в качестве параметра первоначальное значение для свойства Name экземпляров Player.

И, наконец, последнее, что потребуется сделать - это предоставить метод типа bool с именем HasWon (), возвращающий значение true только в том случае, если все карты на руках игрока относятся к одной масти (что является простым условием для победы). Ниже приведен код, который нужно добавить в Player. cs:

using System;

using System.Collections.Generic; using System.Linq; using System.Text; using Chl3CardLib;

namespace Chl3CardClient {

public class Player

private Cards hand; private string naxne; public string Naxne

return naxne;

public Cards PlayHand

return hand;

private Player()

public Player (string newNaxne) {

naxne = newNaxne;

hand = new Cards () ;



1 ... 121 122 123 [ 124 ] 125 126 127 ... 396

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика