
ezM0YUQ7Uv
.pdf21
9.Добавьте в класс BankAccount переменную tranQueue, объявив ее как private Queue tranQueue = new Queue();
10.В методе Deposit перед тем как возвратить значение accBal создайте транзакцию, используя amount в качестве параметра, и добавьте ее в очередь с помощью метода Enqueue.
11.В методе Withdraw создайте транзакцию и добавьте ее в tranQueue с помощью метода Enqueue.
12.Проверьте работу программы. Для этого добавьте в класс BankAccount метод Transactions как public. Метод должен иметь тип Queue и возвращать tranQueue.
13.В классе CreateAccount модифицируйте метод Write так, чтобы отображалась информация о транзакциях для каждого счета. Очереди используют интерфейс IEnumerable, что означает возможность применения конструкции foreach. В теле цикла foreach добавьте вывод даты и времени, а также amount для каждой транзакции, используя методы Amount и When.
14.Добавьте в метод Main выражения, которые кладут деньги на счет и снимают с него. Сделайте это для всех четырех счетов acc1, acc2, acc3, acc4.
15.Проверьте работу программы. Откомпилируйте программу. Откорректируйте ошибки и сохраните результат. Полученный листинг упражнения 2 сохраните для отчета.
Упражнение 3. Создание деструктора. Необходимо добавить в программу деструктор.
1.Откройте Visual Studio, если она не была открыта. Откройте проект, созданный в предыдущих упражнениях.
2.Добавьте в класс BankTransaction команду using System.IO;.
3.В класс BankTransaction добавьте деструктор ~BankTransaction().
4.В теле деструктора ~BankTransaction() определите несколько выражений. Код должен выглядеть так:
~BankTransaction()
{
StreamWriter swFile = File.AppendText("Transactions.Dat");
22 swFile.WriteLine("Date/Time: {0}\tAmount:
{1}", when, amount); swFile.Close();
GC.SuppressFinalize(this);
}
5.Откомпилируйте программу. Откорректируйте ошибки.
6.Проверьте работу деструктора. Для этого внесите изменения в класс CreateAccount. Удалите (закомментируйте) определения переменных acc1, acc2, acc3, acc4 и оставшийся от предыдущего упражнения код. Определите переменную acc1 как BankAccount. Примените методы Deposit и Withdraw с разными параметрами. Выведите значение acc1 с помощью метода Write на консоль.
7.Откомпилируйте программу. Откорректируйте ошибки и сохраните результат.
8.Уточните, что в папке bin\debug создается файл Transactions.Dat. Откройте файл с помощью блокнота. Полученный листинг упражнения 3 сохраните для отчета.
Упражнение 4. Работа с деструктором. Используйте проект, который
был создан в предыдущих упражнениях.
1.В класс BankTransaction добавьте следующий код: public void Dispose()
{
Finalize();
}
2.После него должен быть определен деструктор (см. упражнение 3).
3.Отредактируйте класс BankAccount. Добавьте using System; в начало программы.
4.Определите переменную dead как private bool и инициализируйте ее в false.
5.Добавьте метод Dispose() как public void. У метода нет параметров. В теле метода проверьте значение переменной dead. Если значение равно true, то выйдите из метода. Если false, то запустите итерационную процедуру для всех объектов BankTransaction в tranQueue и вызывайте метод Dispose() каждый раз. Используйте цикл foreach. Вызовите GC.SuppressFinalize(this), чтобы предотвратить сборку мусора. Установите для переменной dead значение true.
23
6.Откомпилируйте программу. Откорректируйте ошибки и сохраните результат. Покажите результат преподавателю.
7.Полученный листинг упражнения 4 сохраните для отчета.
Лабораторная работа № 7 ИСПОЛЬЗОВАНИЕ НАСЛЕДОВАНИЯ С ПРИМЕНЕНИЕМ
ИНТЕРФЕЙСОВ
Упражнение 1. Преобразование файла, содержащего код на языке C#, в файл на языке HTML. Необходимо внести изменения в программу, представленную в папке Starter. Так как программа в процессе выполнения упражнения многократно меняется, то необходимо фиксировать промежуточные результаты для отчета.
Изучите классы и интерфейсы, находящиеся в файлах Itoken.cs, Itoken_visitor.cs, source_file.cs. Взаимодействие представленных в них классов и интерфейсов описано в файле IToken.cd.
1.Откройте Visual Studio. В меню File выберите New, затем выберите Project. Из списка шаблонов выберите Console Application. Впишите название проекта, например ColorToken.
2.Откройте файл null_token_visitor.cs. Обратите внимание на то, что класс NullTokenVisitor является производным от интерфейса ITokenVisitor.
3.Добавьте в класс NullTokenVisitor метод Visit и определите его как public virtual void. У метода должен быть один параметр. Тело метода должно быть пустым:
public virtual void Visit(ILineStartToken t) {}
4.Повторите предыдущий шаг для всех методов Visit, объявленных для интерфейса ITokenVisitor. Код программы находится в файле IToken.cs.
5.Удалите метод Populate.
6.Сохраните результат. Откомпилируйте программу. Откорректируйте ошибки. Полученный листинг упражнения 1 сохраните для отчета.
7.Добавьте в класс NullTokenVisitor метод Test.
8.Сохраните результат. Откомпилируйте программу. Откорректируйте ошибки. Полученный листинг сохраните для отчета.
9.Измените определение класса NullTokenVisitor, сделав его абстрактным.
10.Снова сохраните результат. Откомпилировав программу, получите ошибки. Объясните, чем вызвано их появление.
24
11.Удалите метод Test.
12.Откройте файл html_token_visitor.cs. Создайте класс HTMLTokenVisitor
так, чтобы он был производным от абстрактного класса
NullTokenVisitor.
13.Откройте файл main.cs и добавьте 2 выражения в статический метод InnerMain. Первое выражение должно объявлять переменную visitor типа HTMLTokenVisitor. Второе выражение должно передавать переменную visitor как параметр в методе Accept с уже объявленной переменной source.
14.Сохраните результат. Откомпилируйте программу. Программу запустите из командной строки из каталога Bin\debug рабочего проекта. Полученный листинг сохраните для отчета.
15.Добавьте нестатический метод Visit в класс HTMLTokenVisitor. Метод имеет один параметр line, определенный как ILineStartToken. Используйте метод Console.Write для отображения значения line.Number().
16.Сохраните результат. Откомпилируйте программу. Отметьте, что произойдет.
17.Измените HTMLTokenVisitor. Visit (ILineStartToken). Сохраните результат. Откомпилируйте программу.
18.Вернитесь к HTMLTokenVisitor. Определите перегрузку метода Visit.
19.Сохраните результат. Откомпилируйте программу.
20.Отредактируйте HTMLTokenVisitor так, чтобы исходный файл отображался в файл HTML. Для этого добавьте в класс
HTMLTokenVisitor перегрузку метода Visit.
21.Сохраните результат. Откомпилируйте программу.
22.Повторите предыдущий шаг перегрузки методов 4 раза для Visit для параметров, имеющих тип ICommentToken, IKeywordToken, IWhiteSpaceToken и IOtherToken соответственно.
23.Перейдите к преобразованию файла token.cs к token.html.
24.Используйте Internet Explorer для просмотра полученного файла token.html.
25.Измените определение метода Visit(ILineStartToken).
26.Сохраните результат. Откомпилируйте программу.
27.В папке Bin\debug рабочего проекта поместите файл token.cs.
25
28.Используйте Internet Explorer для просмотра полученного файла token.html.
29.Добавьте еще одно определение метода в HTMLTokenVisitor.
30.Сохраните результат. Откомпилируйте программу.
31.В папке Bin\debug рабочего проекта поместите файл token.cs.
32.Используйте Internet Explorer для просмотра полученного файла token.html.
33.Добавьте определение метода в HTMLTokenVisitor.
34.Сохраните результат. Откомпилируйте программу.
35.Преобразуйте файл token.cs. в HTML.
36.Используйте Internet Explorer для просмотра полученного файла token.html.
37.Измените определение HTMLTokenVisitor.Visit(ICommentToken), чтобы использовать метод FilteredWrite вместо Console.Write.
38.Аналогично выполните замену для метода HTMLTokenVisitor.Visit (IOtherToken).
39.Сохраните результат. Откомпилируйте программу.
40.Преобразуйте файл token.cs. в HTML.
41.Используйте Internet Explorer для просмотра полученного файла token.html.
42.Проверьте использование файла code_style.css. Найдите в этом файле фрагмент кода SPAN.LINE_NUMBER.
43.Сохраните результат. Откомпилируйте программу. Ошибки пока останутся. Переопределите класс HTMLTokenVisitor следующим образом:
public class HTMLTokenVisitor : ITokenVisitor
{
…
Public void Visit(IDirectiveToken token)
{
SpannedFilteredWrite(“directive”, token);
…
}
}
44.Откомпилируйте программу. Сохраните результат.
26
Лабораторная работа № 8 СОЗДАНИЕ И ИСПОЛЬЗОВАНИЕ ДЕЛЕГАТОВ
Упражнение 1. Использование именованного делегата. Необходимо явно объявить делегат, реализовать его и использовать.
1.Откройте Microsoft Visual Studio. Создайте новый проект. Назовите его
«OopLabs.Delegates».
2.Внутри класса Program объявите делегат, реализующий журналирование заданного сообщения с сигнатурой void Log(string):
using System; using System.IO;
namespace OopLabs.Delegates
{
class Program
{
private delegate void Log(string message); static void Main()
{
Console.ReadKey();
}
}
}
3.Реализуйте метод DoSomething(), принимающий в качестве аргумента делегат типа Log. Метод должен имитировать операцию, требующую журналирования:
static void DoSomething(Log log)
{
log(DateTime.Now + ": log message");
}
4.Реализуйте метод LogToFile, имеющий такую же сигнатуру, как и делегат. Метод должен выводить переданное ему в качестве параметра сообщение в текстовый файл. В примере ниже текстовый файл расположен в каталоге «Мои документы»:
static void LogToFile(string message)
{
string myDocsPath =
27
Environment.GetFolderPath(Environment.SpecialFolde
r.MyDocuments);
string logFilePath = Path.Combine(myDocsPath, "log.txt");
File.AppendAllText(logFilePath, message + Environment.NewLine);
}
5.Добавьте в метод Main() вызов функции DoSomething, передавая ей в качестве аргумента метод LogToFile():
static void Main()
{
DoSomething(LogToFile);
Console.ReadKey();
}
6.Откомпилируйте программу и запустите ее. Убедитесь, что в файле создалась запись. При необходимости исправьте ошибки.
7.Сохраните результат для отчета.
Упражнение 2. Использование анонимного делегата и лямбда-
выражения. Необходимо создать делегат, реализующий вывод сообщения на консоль. В отличие от предыдущего упражнения делегат должен быть анонимным, т. е. не иметь имени. Анонимные делегаты появились в .NET 2.0, а лямбда-выражения (являющиеся более удобным способом записи анонимных делегатов) – в .NET 3.0.
1.Добавьте в метод Main() вызов метода DoSomething(), передав ему в качестве параметра объявление анонимного делегата, выводящего сообщение на консоль.
static void Main()
{
DoSomething(LogToFile); DoSomething(delegate(string message) {
Console.WriteLine(message); }); Console.ReadKey();
}
2.Откомпилируйте программу и запустите ее. Убедитесь, что запись добавилась в файл и вывелась на экран.
3.Сохраните результат для отчета.
28
4.Добавьте еще один вызов метода DoSomething(), изменив явное определение анонимного делегата лямбда-выражением:
static void Main()
{
DoSomething(LogToFile); DoSomething(delegate(string message) {
Console.WriteLine(message); }); DoSomething(message =>
Console.WriteLine(message));
Console.ReadKey();
}
5.Откомпилируйте программу и запустите ее. Убедитесь, что запись добавилась в файл и дважды вывелась на экран.
6.Сохраните результат для отчета.
7.Добавьте еще один вызов метода DoSomething(), изменив лямбдавыражение самим методом Console.WriteLine:
static void Main()
{
DoSomething(LogToFile); DoSomething(delegate(string message) {
Console.WriteLine(message); }); DoSomething(message =>
Console.WriteLine(message));
DoSomething(Console.WriteLine);
Console.ReadKey();
}
8.Откомпилируйте программу и запустите ее. Убедитесь, что запись добавилась в файл и трижды вывелась на экран.
9.Сохраните результат для отчета.
Упражнение 3. Использование типа Action<T>. Необходимо изменить делегат Log более общим типом Action<T>. Делегаты Action<…> и Func<…> (возвращающий значение) появились в .NET 3.5, и их применение предпочтительнее, чем специфичных (такие как Log), поскольку они не требуют отдельного определения сигнатуры.
1.Измените тип параметра метода DoSomething() с Log на более общий и удобный Action<string>:
static void DoSomething(Action<string> log)
29
{
log(DateTime.Now + ": DoSomething()");
}
2.Удалите объявление делегата Log.
3.Откомпилируйте программу и запустите. Убедитесь, что проделанные изменения не нарушили работоспособность программы.
4.Сохраните результат для отчета.
Лабораторная работа № 9 ИСПОЛЬЗОВАНИЕ LINQ
Подготовка к выполнению работы. Откройте Visual Studio. Создайте новый проект типа Windows Forms Application с названием OopLabs.Linq.
Добавьте в проект файл Artist.cs. Изучите описание класса Album. Класс хранит информацию о музыкальном альбоме: имя исполнителя, название, дату выхода. Кроме того, определение класса включает статический метод Album.GetAlbums(), возвращающий список некоторых альбомов нескольких групп.
Упражнение 1. Вывод списка групп. Необходимо явно объявить делегат, реализовать его и использовать. Разместите на главной форме надпись (объект Label) «Исполнители». Ниже надписи разместите список (ListBox). Добавьте обработчик события «Load» формы, выводящий список групп, альбомы которых возвращаются функцией Album.GetAlbums(). Для этого присвойте параметру DataSource списка нужное значение. Используйте функции LINQ Select() для отображения коллекции, Distinct() для удаления дубликатов и ToList() для конвертации коллекции в список:
private void MainForm_Load(object sender, EventArgs e)
{
ArtistsListBox.DataSource = Album.GetAlbums()
.Select(album
=> …)
.Distinct()
.ToList();
30
}
Откомпилируйте проект и запустите. Откорректируйте ошибки и сохраните результат.
Упражнение 2. Вывод альбомов для групп. На форме справа от созданных ранее элементов разместите надпись «Альбомы» и еще один список. Добавьте обработчик события «SelectedIndexChanged» списка исполнителей, выводящий в список альбомов альбомы выбранного исполнителя. Используйте функцию LINQ Where для фильтрации коллекции альбомов. Для получения выделенного пункта списка исполнителей используйте свойство объекта ListBox SelectedItem:
private void ArtistsListBox_SelectedIndexChanged(object sender, EventArgs e)
{
AlbumsListBox.DataSource = Album.GetAlbums()
.Where(album
=> …)
.ToList();
}
Откомпилируйте проект и запустите его.
Упражнение 3. Сортировка списков исполнителей и альбомов.
Измените созданный ранее обработчик события «SelectedIndexChanged» списка исполнителей так, чтобы альбомы сортировались по дате выхода от более поздних к более ранним. Используйте для этого функцию
OrderByDescending():
AlbumsListBox.DataSource = Album.GetAlbums()
.Where(album => …)
.OrderByDescending(album => …)
.ToList();
Измените созданный ранее обработчик события «Load» формы так, чтобы исполнители выводились в список в алфавитном порядке. Используйте для этого функцию LINQ OrderBy(). Откомпилируйте проект и запустите его.