Практические задания по курсу "Язык CSharp и платформа .NET" — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Задание 1б)
(Задание 1б (Занятие 2))
 
(не показаны 333 промежуточные версии 2 участников)
Строка 1: Строка 1:
 +
[[Страница_курса_Язык_CSharp_и_платформа_.NET | К основной странице курса]]
 +
 +
__NOTOC__
 
===Практические задания по курсу "Язык C# и платформа .NET"===
 
===Практические задания по курсу "Язык C# и платформа .NET"===
  
====Задание 1 (начало)====
+
[http://it.mmcs.sfedu.ru/docs/Miks/CSC/Lection1-2013.pdf Материалы к заданию 1]
  
1.1. Откомпилировать простейшую библиотеку .dll и простейшую программу .exe, вызывающую методы библиотеки, с помощью csc.exe.
+
===Задания к зачету===
 +
 +
==== Задание 1 (Занятие 1)====
 +
 
 +
1.1. Откомпилировать простейшую библиотеку .dll с функцией, складывающей два числа, и простейшую программу .exe, вызывающую этот метод библиотеки, с помощью csc.exe.
 
Записать размер полученных файлов.
 
Записать размер полученных файлов.
  
1.2. Просмотреть метаданные в сборках .dll и .exe с помощью ILDasm
+
1.2. Просмотреть метаданные в сборках .dll и .exe с помощью ILDasm и с помощью ILSpy
  
 
1.2a. Создать простейшее оконное приложение и записать его размер.
 
1.2a. Создать простейшее оконное приложение и записать его размер.
  
1.3. Написать аналогичную dll на PascalABC.NET, просмотреть метаданные с помощью ildasm и вызвать метод dll в программе на C#
+
<source lang="CSharp">
 +
using System;
 +
using System.Windows.Forms;
 +
class MainWin: Form
 +
{
 +
  static void Main()
 +
  {
 +
    Application.Run(new MainWin());
 +
  }
 +
}
 +
</source>
 +
1.3. Написать dll на PascalABC.NET, содержащую функцию add, складывающую 2 числа. Просмотреть метаданные с помощью ildasm или ILSpy (скачать ILSpy из Интернета) и вызвать функцию add из PascalABC.NET-dll в программе на C#
  
 
1.4. Вызвать метод из dll, написанной на C#, в программе на PascalABC.NET
 
1.4. Вызвать метод из dll, написанной на C#, в программе на PascalABC.NET
  
====Задание 1а====
+
Для подключения dll в PascalABC.NET используйте следующий синтаксис:
1.5. Откомпилировать сборки exe и dll с помощью Visual Studio в режимах Debug и Release. Сравнить размеры полученных файлов.
 
  
1.6. Аналогично обеспечить межъязыковое взаимодействие VB.NET <--> Managed C++
+
<source lang="Delphi">
 +
{$reference my.dll}
 +
...
 +
</source>
 +
1.5. Вызвать метод из dll, написанной на PascalABC.NET, в программе на C#
  
====Задание 1б====
+
Для написания dll на PascalABC.NET используйте следующий синтаксис:
1.7. Сравнить скорость работы вычислительного алгоритма на языках C#, C++, Java, PascalABC.NET, Free Pascal
+
<source lang="Delphi">
:a) <math>\sum_{i,j\le n}\frac{1}{i*j} </math>, n - достаточно большое
+
library mylib;
:б) <tt>Σ(i,j=1..n)1/a[i]/a[j]</tt>, n - достаточно большое
 
  
: <math>\sum_{i,j\le n}\frac{1}{i*j}</math>
+
function f(a,b: integer) := a + b;
  
Сравнивать скорость в Debug и Release - конфигурациях.  
+
end.
 +
</source>
 +
1.6. Откомпилировать сборки exe и dll с помощью Visual Studio в режимах Debug и Release. Сравнить размеры полученных файлов.
  
Для .NET-языков сравнить IL-код для циклов с помощью ildasm и выявить неэффективность генерации кода.
+
==== Задание 1б (Занятие 2)====
 +
1.7. Сравнить скорость работы вычислительного алгоритма на языках C#, C++, Java, PascalABC.NET, Python
 +
:a) Сумма(i=1..n)(1/(i*j)), n - достаточно большое
 +
:б) Сумма(i=1..n)(1/(a[i]*a[j])), n - достаточно большое
 +
:в) Произведение квадратных матриц n x n, n - достаточно большое
  
====Задание 1в====
+
[https://docs.google.com/spreadsheet/ccc?key=0AmqiCR41-J01dHliQ2FMSFVLQW1XZldsNVRnaFduUnc&usp=sharing Таблица сравнения скорости для группы 4.1]
1.8. Создать сборку, содержащую статический класс MyArray со статическими функциями, реализующими алгоритмы работы с одномерными и двумерными массивами произвольного типа T. Функции должны описываться в виде
 
  
static type Name<T>(T[] arr, anotherparams)
+
Для замера времени в PascalABC.NET воспользоваться функцией Milliseconds, возвращающей время с начала работы программы в секундах. В настройках отключить режим Debug и запускать программу по Shift-F9.
  
Для одномерных массивов:
+
Для PascalABC.NET в настройках опций компиляции отключить "Генерировать отладочную информацию" и "Удалять exe после выполнения". Для компиляции программы воспользоваться командой Компилировать (Ctrl-F9) и запускать exe файл вне среды, либо запускать по Shift-F9 в режиме без связи с оболочкой.
FillRandom
 
Print
 
Insert
 
Delete
 
CycleShiftLeft
 
CycleShiftRight
 
Concat - конкатенация двух массивов в один
 
Compare - сравнение двух массивов
 
Find - поиск
 
  
Для двумерных массивов:
+
Занести все данные по скорости в таблицу
FillRandom
 
Print
 
Transpose
 
DeleteRow
 
DeleteCol
 
Find - поиск
 
Submatrix - вырезание подматрицы
 
  
Написать программу, тестирующую все указанные функции.
+
В пунктах б) и в) заполнить массив a и матрицы случайными числами в диапазоне от 1 до 1.1. Для генерации случайных чисел в .NET пользоваться классом Random:
  
'''Замечание 1.''' Для заполнения случайными числами воспользоваться классом <tt>Random</tt>.
+
<source lang="CSharp">Random r = new Random();
 +
r.NextDouble();</source>
  
'''Замечание 2.''' Поскольку некоторые функции меняют размеры массива, рекомендуется вторым параметром для массива передавать по ссылке его текущее количество элементов, например:
+
Сравнивать скорость в Debug и Release - конфигурациях.  
static void Insert<T>(T[] arr, ref int len, T x)
 
  
'''Замечание 3.''' Для одномерных массивов доступно на чтение свойство a.Length. Для двумерных массивов для создания и использования:
+
Для .NET-языков сравнить IL-код для циклов с помощью ildasm и выявить неэффективность генерации кода.
int [,] a = new int[5,6];
 
a.GetLength(0);
 
a.GetLength(1);
 
a.Rank
 
  
====Задание 2 на наследование и полиморфизм====
+
====Задание 2 на наследование и полиморфизм (Занятие 3)====
 
2.1. Создать иерархию классов <code>Person-Student-Teacher</code>. Каждый класс – в своей сборке. В каждом классе должны быть свойства, а также виртуальная функция <code>Print</code> и переопределенная функция <code>ToString()</code>. Основная программа создает массив объектов Person или их наследников, после чего выдает его на экран.
 
2.1. Создать иерархию классов <code>Person-Student-Teacher</code>. Каждый класс – в своей сборке. В каждом классе должны быть свойства, а также виртуальная функция <code>Print</code> и переопределенная функция <code>ToString()</code>. Основная программа создает массив объектов Person или их наследников, после чего выдает его на экран.
 
У каждого Teacher должен быть список <code>Students</code>, которыми он руководит, у каждого <code>Student - Teacher</code>, который им руководит.
 
У каждого Teacher должен быть список <code>Students</code>, которыми он руководит, у каждого <code>Student - Teacher</code>, который им руководит.
  
2.2. Для классов <code>Person-Student-Teacher</code> реализовать <code>ToString(), Equals(), ==, !=, GetHashCode()</code>. С помощью <code>is</code>, <code>as</code>, <code>GetType</code> определить, сколько в контейнере персон, студентов и преподавателей и перевести всех студентов на следующий курс.
+
'''Замечание.''' В процессе реализации возникнет такая ошибка как циклическая зависимость сборок: сборка Student зависит от сборки Teacher и наоборот. Для устранения этой ошибки рекомендуется создать класс Student без поля Teacher, после чего создать производный класс StudentWithAdvisor с полем Teacher в отдельной сборке.
 +
 
 +
2.2. Для классов <code>Person-Student-Teacher</code> реализовать и оттестировать <code>ToString(), Equals(), GetHashCode()</code>.
 +
 
 +
2.3. Для классов <code>Person-Student-Teacher</code> реализовать статические методы RandomPerson, RandomStudent, RandomTeacher, которые возвращают случайного из некоторого статического массива.
 +
 
 +
2.4. С помощью <code>is</code>, <code>as</code>, <code>GetType</code> определить, сколько в массиве персон, студентов и преподавателей и перевести всех студентов на следующий курс.
  
2.3. Для классов <code>Person-Student-Teacher</code> реализовать глубокое клонирование, определив виртуальный метод Clone(). Клон должен возвращать точную копию по значению и типу. Проиллюстрировать Clone на примере контейнера персон.
+
2.5. Для классов <code>Person-Student-Teacher</code> реализовать глубокое клонирование, определив виртуальный метод Clone(). Клон должен возвращать точную копию по значению и типу. Проиллюстрировать Clone на примере контейнера персон - должны создаваться клоны объекты ровно тех типов, которые содержатся в исходном контейнере.
  
2.4. Используя метод <code>GetType()</code> класса <code>Student</code> и метод <code>BaseType()</code> класса <code>Type</code>, вывести всех предков класса <code>Student</code> (написать общий метод)
+
(нет) 2.6. Используя метод <code>GetType()</code> класса <code>Student</code> и метод <code>BaseType()</code> класса <code>Type</code>, вывести всех предков класса <code>Student</code> (написать общий метод)
  
'''2.5. (не нужно)''' Проиллюстрировать использование полиморфизма для модификации некоторого кода в будущем. Виртуальные методы должны выполнять роль сменных блоков, действие которых будет в будущем переопределено.
 
  
 
'''Замечание 1.''' Свойства ("умные" поля) определяются так:
 
'''Замечание 1.''' Свойства ("умные" поля) определяются так:
  public int age;
+
  private int age;
 
  public int Age {
 
  public int Age {
 
   get { return age; }
 
   get { return age; }
Строка 104: Строка 114:
 
3.0. Для классов Person-Student-Teacher реализовать ==, !=
 
3.0. Для классов Person-Student-Teacher реализовать ==, !=
  
3.1. Создать структуру <tt>Complex</tt> с перегруженными операциями, а также с возможностью приведения типа double->complex. Должны быть реализованы также <tt>ToString()</tt>, <tt>Equals()</tt>, <tt>==</tt>, <tt>!=</tt>
+
3.1. Создать класс <tt>Frac</tt> с перегруженными операциями + - * / , а также с возможностью приведения типа Frac->double. Должны быть реализованы также <tt>ToString()</tt>, <tt>Equals()</tt>, <tt>==</tt>, <tt>!=</tt>. Вычислить значение полинома в точке. Все коэффициенты и x должны иметь тип <tt>Frac</tt>. Сравнить производительность в случае реализации Frac как класса и как структуры.
 +
 
 +
[https://docs.google.com/spreadsheets/d/1E6HD8t8bilh16LbkRkuKigXL2TSrqaUDbJGTnmmd72w/edit#gid=1098189343 Таблица сравнения скорости Frac] (см. лист 2)
 +
 
 +
3.2. Создать структуру <tt>Complex</tt> с перегруженными операциями, а также с возможностью приведения типа double->complex. Должны быть реализованы также <tt>ToString()</tt>, <tt>Equals()</tt>, <tt>==</tt>, <tt>!=</tt>. Сравнить производительность в случае реализации Complex как класса и как структуры.
  
3.2. Создать класс <tt>Frac</tt> с перегруженными операциями + - * / , а также с возможностью приведения типа Frac->double. Должны быть реализованы также <tt>ToString()</tt>, <tt>Equals()</tt>, <tt>==</tt>, <tt>!=</tt>. Вычислить значение полинома в точке. Все коэффициенты и x должны иметь тип <tt>Frac</tt>.
+
//3.3. Используя класс <tt>Frac</tt>, реализовать метод Гаусса для решения системы линейных уравнений из n уравнений с n неизвестными и с рациональными коэффициентами, заданными типом Frac. Найти точное решение, представляющее собой List<Frac>.
  
 
'''Замечание 1.''' Операции реализуются как статические методы:  
 
'''Замечание 1.''' Операции реализуются как статические методы:  
Строка 115: Строка 129:
 
explicit означает явное приведение типа, вместо него может стоять implicit - неявное приведение типа.
 
explicit означает явное приведение типа, вместо него может стоять implicit - неявное приведение типа.
  
====Задание 4 на индексаторы====
+
==== Задание 4 на индексаторы====
  
 
4.1. Создать класс, реализующий битовый массив на основе обычного, используя индексные свойства.
 
4.1. Создать класс, реализующий битовый массив на основе обычного, используя индексные свойства.
  
* 4.2. Создать класс RGB, реализующий индексное свойство, возвращающее по строке с именем цвета цвет System.Drawing.Color.
+
4.2. Создать класс ассоциативного массива, используя два списка List - список ключей и список значений. Основная операция: x = d[K] (на чтение) и d[K] = V (на запись)
 +
 
 +
Индексные свойства создаются следующим образом:
 +
 
 +
<source lang="Csharp">private Dictionary<string,int> a;
 +
public int this[string s] {
 +
  get { return a[s]; }
 +
  set { a[s] = value; }
 +
}</source>
 +
 
 +
====Задание 5 на интерфейсы====
 +
 
 +
5.1. Проверить, как работает явная и неявная реализация методов интерфейса. Для этого '''явно''' реализовать в классах Person и Student интерфейс 
 +
<source lang="Csharp">interface IPrintable {
 +
  void Print();
 +
}
 +
</source>
 +
и вызвать этот метод, используя переменную типа интерфейс. Заметим, что старый метод Print также можно оставить.
 +
 
 +
5.2. В классе Student реализовать интерфейс IComparable<Student>. Воспользовавшись Array.Sort, отсортировать массив студентов.
 +
 
 +
5.3. Реализовать интерфейс IComparer<Student> в классе StudentComparer, вложенном в Student. Параметром его конструктора должен выступать критерий сортировки.
 +
Реализовать в классе Student несколько статических свойств по количеству критериев сортировки (например, Student.SortByGroup).
 +
Воспользовавшись второй формой Array.Sort, отсортировать массив студентов по разным критериям.
 +
 
 +
5.4. Реализовать в классах Person-Student-Teacher интерфейс ICloneable и проиллюстрировать его использование.
 +
 
 +
5.5. Реализовать в классе Person интерфейс IDisposable и убедиться в корректности его работы в операторе using
 +
 
 +
Интерфейс IDisposable имеет вид:
 +
<source lang="Csharp">interface IDisposable {
 +
  void Dispose();
 +
}
 +
</source>
 +
Он используется для детерминированного освобождения ресурсов в стиле C++, метод Dispose играет роль деструктора. Если класс My поддерживает интерфейс IDisposable, то его можно использовать в операторе using:
 +
<source lang="Csharp">
 +
using (My m = new My())
 +
{
 +
 
 +
} // в конце гарантированно вызовется Dispose</source>
  
* 4.3. Создать класс ассоциативного массива, используя два списка.
+
В методе Dispose() класса Person достаточно выдавать диагностическое сообщение о том, что метод Dispose() вызван.
  
====Задание 5 на строки====
+
5.6. Создать контейнер Persons, который можно было бы использовать в foreach. Для этого поместить в него поле List<Person> list и метод Add(Person p), а также реализовать
 +
интерфейс IEnumerable<Person>, используя в методе GetEnumerator конструкцию yield return.
 +
 
 +
Пример реализации:
 +
<source lang="Csharp">
 +
    public class CustomContainer: IEnumerable<int>
 +
    {
 +
        public IEnumerator<int> GetEnumerator()
 +
        {
 +
            for (int i = 0; i < 10; i++)
 +
                yield return i;
 +
        }
 +
        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
 +
    }</source>
 +
 
 +
Заполнить контейнер Persons персонами и студентами, используя его метод Add. После этого воспользоваться методом foreach по данному контейнеру, выдавая всех персон и студентов в контейнере. Перед каждой персоной или студентом должен выводиться порядковый номер во внутреннем списке.
  
5.1. '''(не надо)''' Проверить механизм интернирования строк
 
  
5.2. Дана строка слов. Убрать лишние пробелы и упорядочить слова по алфавиту. Воспользоваться методом расщепления s.Split(массив разделителей,System.StringSplitOptions.RemoveEmptyEntries) строки на массив строк и методом string.Join(разделитель,ss) слияния массива строк в строку. Аналогично упорядочить слова по длине, записав их в единой строке.
+
5.7. Реализовать обобщенную функцию MinIndex, возвращающую пару (индекс, МинимальныйЭлемент) в массиве элементов типа T. Для этого наложить в секции where ограничений на параметры обобщения условие where T: IComparable<T>. Результат возвращать в виде Tuple<int,T>. Если в массиве нет элементов, то индекс минимального равен -1, а минимальный равен default(T) - значению по умолчанию для типа T.
  
5.3. Вводятся вещественные числа (возможно, на нескольких строках), конец ввода - 0. На одной строке может быть несколько вещественных чисел, а также не числа. Используя метод Append класса <tt>StringBuilder</tt>, сформировать строку, в которой эти вещественные числа разделены одним пробелом, и количество цифр в дробной части равно 1. Не числа - игнорировать. Для разбора вещественного использовать double.TryParse, для форматирования вещественного - d.ToString (формат вывода для вещественного с 1 цифрой в дробной части)
+
====Задание 6 на yield====
  
5.4. Используя тот факт, что для объекта <tt>StringBuilder</tt> доступна операция обращения по индексу [] '''на запись''', преобразовать в строке слов первую букву каждого слова в заглавную.
+
6.1. Используя yield, реализовать и оттестировать метод расширения - генератор n членов арифметической прогрессии с первым элементом a0 и шагом d.
 +
Для вывода реализовать метод Print, использующий yield и выводящий любую последовательность.
  
5.5. Используя различные кодировки System.Text.Encoding, преобразовать строку "Спецкурс C# и платформа .NET 2011" в массив байтов. Для этого использовать GetBytes соответствующей кодировки:
+
6.2. Реализовать метод-генератор бесконечной последовательности значений val. Для тестирования реализовать метод
 +
  IEnumerable<T> TakeN<T>(this IEnumerable<T> seq, int n)
 +
который возвращает n первых членов бесконечной последовательности.
  
System.Text.Encoding.UTF8.GetBytes(s);
+
6.3. Реализовать метод - генератор бесконечной последовательности случайных чисел.
  
Для того чтобы получить список всех поддерживаемых кодировок, воспользуйтесь методом
+
6.4. Реализовать метод - генератор бесконечной арифметической прогрессии.
  
Encoding.GetEncodings();
+
6.4а. Реализовать метод - генератор бесконечной последовательности чисел Фибоначчи.
  
возвращающим массив объектов <tt>EncodingInfo</tt>.
+
6.5. Реализовать метод расширения - генератор бесконечной последовательности циклически повторяющихся элементов последовательности seq
  
5.6. Используя System.Globalization.NumberFormatInfo, переопределить разделитель в вещественном числе с запятой на точку (в русских версях windows по умолчанию - запятая). Для этого создать экземпляр NumberFormatInfo и переопределить в нем свойство NumberDecimalSeparator на '.'. Для преобразования вещественного в строку воспользоваться d.ToString(nfi), где nfi - переменная типа NumberFormatInfo. Для считывания вещественного с другим разделителем воспользоваться преобразованием строки в вещественное
+
6.6. Реализовать метод расширения, принимающий две последовательности одинаковой длины и возвращающий последовательность пар в виде Tuple<T,T1>
double.Parse(s,nfi);
 
Реализовать на основе этого суммирование всех вещественных, записанных в строке в виде
 
  
  3.14    2.8  4.19  5.3
+
6.7. Реализовать метод расширения, возвращающий по последовательности целых отфильтрованную последовательность, состоящую только из четных элементов исходной последовательности, только из элементов исходной последовательности, удовлетворяющей определенному условию
  
и вывести результат в виде
+
6.8. Реализовать метод расширения, возвращающий по последовательности целых значений преобразованную последовательность квадратов этих значений (последовательность, полученную произвольной функцией преобразования).
  
3.14 + 2.8 + 4.19 + 5.3 = ...
+
6.9. Реализовать метод расширения, принимающий две последовательности элементов одного типа и возвращающий последовательность чередующихся элементов исходных последовательностей
  
5.7. Используя объект System.Globalization.DateTimeFormatInfo, переопределить свойство DateSeparator на ';'. Проверить работу нового формата, выведя текущую дату DateTime.Now в новом формате. Используя указанный формат, считать строку, содержащую две даты в указанном формате и найти дни недели, соответствующие этим датам, а также разницу между этими датами в днях, часах и минутах.
+
6.10. Реализовать метод расширения, возвращающий по последовательности значений последовательность пар рядом стоящих значений:
  
5.8. Считать содержащиеся в строке шестнадцатеричные числа
+
  1 2 3 4 5 ->   (1,2) (2,3) (3,4) (4,5)
   AAFF    BCDF    1FF4    123D9    CC11D3
 
и просуммировать их. Результат выдать в восьмеричной системе счисления.
 
  
====Задание 6 на интерфейсы====
+
====Задание 8 на LINQ====
  
6.1. Проверить, как работает явная и неявная реализация методов интерфейса.
+
[http://edu.mmcs.sfedu.ru/mod/resource/view.php?id=1438 LINQ to Objects (автор М.Э.Абрамян)]
  
6.2. В классе Student реализовыать интерфейс IComparable. Воспользовавшись Array.Sort, отсортировать массив студентов.
+
[http://edu.mmcs.sfedu.ru/mod/resource/view.php?id=1440 LINQ. Выражения запросов (автор М.Э.Абрамян)]
  
6.3. Реализовать интерфейс IComparer в классе StudentComparer, вложенном в Student. Параметром его конструктора должен выступать критерий сортировки. Воспользовавшись второй формой Array.Sort, отсортировать массив студентов по разным критериям.
+
===== Как в дисплейном классе настроить папку для решения заданий LinqBegin из электронного задачника Programming Taskbook =====
  
6.4. Реализовать в классах Person-Student-Teacher интерфейс ICloneable и проиллюстрировать его использование.
+
1. Создать на своем диске папку LINQ
  
6.5. Реализовать интерфейс IDisposable и убедиться в корректности его работы в операторе using
+
2. Установить PTForLinq [http://ptaskbook.com/download/PTforLINQ_v1_1ru.exe отсюда]
  
Интерфейс IDisposable имеет вид:
+
3. Скопировать в свою папку следующие файлы:  
<source lang="Csharp">interface IDisposable {
+
Load.lnk
  void Dispose();
+
results.dat
}
+
 
</source>
+
4. Запустить ярлык Load.lnk, правой мышью выбрать среду Visual Studio
Он используется для детерминированного освобождения ресурсов в стиле C++, метод Dispose играет роль деструктора. Если класс My поддерживает интерфейс IDisposable, то его можно использовать в операторе using:
+
 
<source lang="Csharp">
+
5. Набрать имя выполняемого задания LinqBegin1, LinqBegin2 и т.д., нажать Enter и проигнорировать вопрос, появляющийся при открытии  проекта с заданием в VS.
using (My m = new My())
+
 
 +
===== Пример решения LinqBegin1 =====
 +
<source lang="Csharp">public static void Solve()
 
{
 
{
 +
  Task("LinqBegin1");
 +
  var seq = GetEnumerableInt();
 +
  Put(seq.First(x => x > 0));
 +
  Put(seq.Last(x => x < 0));
 +
}</source>
  
} // в конце гарантированно вызовется Dispose</source>
+
===== Задания из электронного задачника для выполнения =====
6.6. Создать контейнер Students, который можно было бы использовать в foreach. Реализовать интерфейс IEnumerator<Student> двумя способами: самим классом Students и вложенным приватным классом StudentsEnumerator.
+
[http://edu.mmcs.sfedu.ru/mod/resource/view.php?id=1527 Все задания LinqBegin и LinqObjects (М.Э.Абрамян)]
  
====Задание 7 на контейнерные классы====
+
=====Занятие 1 по LINQ=====
 +
# LinqBegin1-2,5-7
  
7.1. Сравнить производительность ArrayList и List<int>
+
=====Занятие 2 по LINQ=====
 +
# LinqBegin21,24,25,27,28,29,31,34,35,36,39,40
  
7.2. Для словаря, состоящего из пар (строка, число), сравнить производительность HashTable, SortedList, SortedDictionary<K,T>, Dictionary<K,T> на больших объемах данных.
+
=====Занятие 3 по LINQ=====
 +
# LinqBegin44,46,48,50,52,53,56,58,60
  
7.3. Дан файл слов. Создать частотный словарь слов, используя SortedDictionary<K,T>. Вывести слова, упорядоченные по алфавиту и по повторяемости.
+
====Задание 9 на LINQObject====
  
====F#. Основы====
+
=====Индивидуальные задания по LinqObj=====
[[Язык F#. Основы]]
 
  
# Найти НОД(a,b)
+
Авилов Арсений        5  22  42  56  77  91
# Найти сумму квадратов чисел от 1 до n
+
Алёхина Диана        6  23  35  55  76  92
# Найти сумму и произведение цифр целого числа
+
Арутюнов Баграт      12 29  41  49  70  87
# Установить, является ли число простым
+
Боброва Елена        7  16  33  45  77  93
# Разложить на простые числа
+
Будаева Екатерина    10 27  38  51  72  89
# Найти 1!+2!+3!+...+n!
+
Деменский Владислав  4  21  37  57  78  83
 +
Дудников Алексей      13 30  39  48  69  88
 +
Жаров Глеб            11 28  40  50  71  86
 +
Иноземцев Эдуард      8  18  44  60  79  94
 +
Какурин Никита        7  24  34  54  75  85
 +
Козак Михаил          3  20  32  58  79  84
 +
Кормиленко Алексей    1 26  43  59  78  92
 +
Лунёв Илья            9  19  37  62  72  95
 +
Мухина Виктория      2  15  32  46  71  91
 +
Осипян Рубен          14 17  33  47  80  90
 +
Пономаренко Сергей    9  16  36  52  73  82
 +
Резник Владислав      14 29  43  61  70  96
 +
Самгин Роман          8  25  31  53  74  81
 +
Сухов Виктор          10 30  44  63  71  97
 +
Тадевосян Эдгар      11 21  35  64  72  98
 +
Тихонов Алексей      1 19  32  47  80  96
 +
Фазилов Алишер        2 20  43  62  71  90
 +
Царик Максимилиан    3 18  46  60  80  91
 +
Черненко Глеб        4  24  43  48  75  85
 +
Шевелёва Александра  5  25  44  54  76  88
 +
Югай Кристина        6  21  45  55  77  89
 +
Яблочкин Иван        7  22  47  57  78  93
  
[[Язык FSharp. Списки, кортежи, записи | Язык F#. Списки, кортежи, записи]]
 
  
====F#. Списки====
+
    14 17  33  47  80  90
Не пользуясь стандартными функциями, реализовать следующие операции для работы со списками:
+
    9  16  36  52  73  82  17.1  10.2  3.1
 +
    14 29  43  61  70  96  17.2а  6.7    5.3
 +
    8  25  31  53  74  81.  16.2в.  12.1.  6.5
 +
     
 +
    10 30  44  63  71  97  16.2б  13.3  5.3
 +
    11 21  35  64  72  98  16.2в. 12.1.  6.5
  
# Найти сумму элементов списка >5
+
==== Задание 10 на файлы и потоки====
# Написать функцию, определяющую, есть ли данный элемент в списке
 
# Написать функцию, определяющую, удовлетворяется ли условие cond для всех элементов списка
 
# Слить 2 списка в один
 
# Выделить n-тый элемент списка
 
# Определить длину списка
 
# Выделить последний элемент списка
 
# Вернуть список без последнего элемента
 
# Инвертировать список
 
# Найти минимальный элемент списка
 
# Найти индекс элемента списка, удовлетворяющего условию cond
 
# Найти СКАЛПР двух списков
 
# Упорядочен ли список по возрастанию
 
  
====Задание 7а на методы расширения====
+
[https://drive.google.com/drive/folders/1VGNa6Zv9Sk1gS9IiS6zbemdu7POHmsSq?usp=sharing Презентация по файлам]
  
7.4. Разработать метод расширения для IEnumerable<T> - вывод на экран, разделяя разделителем, переданным в качестве параметра.
 
  
7.5. Разработать методы расширения для IEnumerable<T> - сдвиг влево на k, сдвиг вправо на k
+
10.1. Сохранить в текстовых файлах русско-английский тест в различных кодировках и затем считать его из этого файла:
  
7.6. Разработать метод расширения для IEnumerable<T>, записывающий значения, удовлетворяющие предикату, в один IEnumerable<T>, а не удовлетворяющие - в другой, и возвращающий пару указанных IEnumerable<T>.
+
а) в однобайтовых: MS DOS, Koi-8, Windows
  
7.7. Разработать метод расширения для IEnumerable<T>, применяющий функцию Func<T,T1>(T t) к каждому элементу и возвращающий IEnumerable<T>
+
б) в Unicode: Utf-8, Utf-16
  
7.8. Разработать метод расширения для IEnumerable<int>, переставляющий элементы на четных и нечетных местах.
+
10.2. Дан текстовый файл. Удалить из него последние 5 строк.
  
====Задание 8 на LINQ====
+
10.3. В текстовом файле записаны вещественные числа (на каждой строчке - несколько, разделены несколькими пробелами, в формате 3.14  2.597) и другие лексемы (не числа). Найти сумму чисел, игнорируя неверные лексемы.
  
Даны коллекции студентов, кафедр, предметов, и коллекция, задающая связь (Idпредмета, Idстудента, дата записи на курс)
+
10.4. Создать типизированный файл целых, затем модифицировать его, возведя все элементы в квадрат.
  
8.1. Вывести 10 первых студентов с максимальным рейтингом
+
10.5. Для данной папки рекурсивно выдать список её файлов и подпапок.
  
8.2. Вывести количество различающихся рейтингов студентов
+
==== Задание 11 на сериализацию====
  
8.3. Вывести все предметы, которые посещает данный студент
+
Для выполнения заданий следует подключить к основной сборке следующие сборки:
 +
System.Runtime.Serialization
 +
System.Runtime.Serialization.Formatters.Soap
  
8.4. Вывести всех студентов, сгруппированных по кафедрам
+
11.1. Используя BinaryFormatter и атрибут [Serializable], сериализовать на диск в бинарном формате объекты классов Student и Teacher, после чего десериализовать. Убедиться, что сериализация работает корректно (для этого десериализовать и вывести на экран повторно). Обратить особое внимание, что класс Teacher содержит поле List<Student>. Попробовать провести сериализацию, используя SoapFormatter. Что не работает? Как это можно исправить (какое поле убрать/не сериализовать)?
  
8.5. Вывести всех студентов, сгруппированных по среднему баллу: от 5 до 4.5, от 4.5 до 4, от 4 до 3 и все остальные
+
11.2. Используя SoapFormatter и атрибут [Serializable], сериализовать на диск в XML формате связный список из нескольких
  
* 8.6. Вывести все пары (студент,курс). Реализовать подзапрос
+
  class Node
 +
  {
 +
    public int data;
 +
    public Node next;
 +
  // конструктор
 +
  }
  
====Задание 9 на файлы и потоки====
+
Затем десериализовать его и убедиться, что все данные сохранились. Посмотреть содержимое XML-файла и понять, за счет чего десериализуется связный список (как восстанавливаются ссылки). Можно ли в этом случае использовать BinaryFormatter?
  
9.1. В текстовом файле записаны вещественные числа (на каждой строчке - несколько, разделены несколькими пробелами) и что-то ещё. Найти сумму чисел, игнорируя неверные лексемы.
+
11.3. Используя класс XMLSerializer, сериализовать-десериализовать объекты класса Student в XML-формате. Использовать атрибуты [XmlAttribute] для полей, которые необходимо сериализовать. Чем отличается XML-представление от SoapFormatter? Понять ограничения этого сериализатора.
  
9.2. Создать типизированный файл целых, затем модифицировать его, возведя все элементы в квадрат.
+
11.4. Используя SoapFormatter, создать структуру, поддерживающую граф объектов и сериализовать-десериализовать граф. Подумать над представлением графа в виде списка инцидентных вершин, не используя List<T>.
  
9.3. Для данной директории рекурсивно выдать список её файлов и поддиректорий.
+
11.5. Используя DataContractSerializer, его методы ReadObject и WriteObject и атрибуты [DataContract] для класса и [DataMember] для открытых полей или свойств, сериализовать на диск в XML-формате объекты класса Student. Вызвав конструктор DataContractSerializer в виде new DataContractSerializer (typeof (Student), new Type[ ]{typeof (SeniorStudent)}), сериализовать-десериализовать также потомков Student типа SeniorStudent.
  
====Задание 10 на сериализацию====
+
==== Задание 12 на рефлексию====
  
* 10.1. Используя BinaryFormatter и атрибут [Serializable], сериализовать на диск в бинарном формате объекты классов Student и Teacher, после чего десериализовать. Добавить в Student список оценок List<int> и ссылку на преподавателя Teacher. Убедиться, что сериализация работает корректно.
+
12.1. Используя механизм отражения, "расшифровать" все классы, содержащиеся в Student.dll. Создать объект класса Student, вызвать его метод, свойство (на чтение и запись).
 +
dll не подключать к проекту статически, использовать Assembly.LoadFrom().
  
* 10.2. Используя DataContractSerializer, его методы ReadObject и WriteObject и атрибуты [DataContract] для класса и [DataMember] для открытых полей или свойств, сериализовать на диск в XML-формате объекты класса Student. Вызвав конструктор DataContractSerializer в виде new DataContractSerializer (typeof (Student), new Type[ ]{typeof (SeniorStudent)}), сериализовать-десериализовать также потомков Student типа SeniorStudent.
+
12.2. Для данного типа (Student) вывести цепочку всех его предков и все интерфейсы, им реализуемые.
  
* 10.3. Используя класс XMLSerializer, сериализовать-десериализовать объекты класса Student в XML-формате. Понять ограничения этого сериализатора.
+
12.3. Используя механизм отражения, динамически создать объект класса Dictionary<string,int>, динамически наполнить его несколькими значениями и динамически вызвать метод (свойство), возвращающее значение по ключу.
  
====Задание 11 на события====
+
12.4. Создать программу автоподключения плагинов к программе. Плагин представляет собой dll, содержащую класс, удовлетворяющий некоторому интерфейсу с одним методом.
 +
Все плагины бросаются в папку с основной программой.
 +
Программа должна анализировать все классы в dll в текущей папке, отбирать те, которые реализуют интерфейс, создавать по одному объекту каждого такого класса и вызывать метод интерфейса для этого объекта.
  
* 11.1. Реализовать механизм обмена сообщениями. В программе должна быть организована "переписка" между как минимум тремя объектами как минимум двух различных классов. Количество типов событий - также не менее трех.
+
==== #Задание 13 на Reflection.Emit====
  
====Задание 12 на рефлексию====
+
13.1. Создайте и вызовите динамический метод, вычисляющий 2018*2018
  
*12.1. Используя механизм отражения, "расшифровать" все классы, содержащиеся в dll. Создать объект класса, вызвать его метод, свойство (на чтение и запись).
+
13.2. Создайте и вызовите динамический метод, выполняющий следующий код:
 +
<source lang="csharp">
 +
var x = 2.0;
 +
var p = Math.Sqrt(x+2);
 +
Console.WriteLine(p);
 +
</source>
 +
13.3. Создайте и вызовите динамический метод, выполняющий следующий код:
 +
<source lang="csharp">
 +
var p = 1;
 +
while (p<=2048)
 +
{
 +
  Console.WriteLine(p);
 +
  p *= 2;
 +
}
 +
</source>
 +
13.4. Сгенерируйте код для программы, выводящей последовательность 20 первых чисел Фибоначчи.
  
*12.2. Для данного типа вывести цепочку всех его предков и интерфейсов, ими реализуемых.
+
13.5. Сгенерируйте код для программы, вычисляющей сумму ряда sum(i=1..n,1.0/i). Сравните программу по производительности с аналогичной программой на C#
  
*12.3. Создать программу автоподключения плагинов к программе. Плагин представляет собой dll, содержащую класс, удовлетворяющий некоторому интерфейсу. Программа должна анализировать все классы в dll, отбирать те, которые реализуют интерфейс, создавать по одному объекту каждого такого класса и вызывать методы интерфейса для этого объекта.
+
====Задание 15 на потоки (Threads)====
  
====Задание 13 на потоки (Threads)====
+
[http://msdn.microsoft.com/ru-ru/library/dd460693%28v=vs.110%29.aspx Материалы по параллельному программированию в .NET на MSDN]
  
13.1. Создать несколько потоков, выводящих на консоль в цикле свой hashcode. Посмотреть порядок вывода.
+
15.1. Создать несколько потоков, выводящих на консоль в цикле свой hashcode. Посмотреть порядок вывода.
 
Добавить Sleep(1), Sleep(10), Sleep(0). Посмотреть изменения в порядке вывода.
 
Добавить Sleep(1), Sleep(10), Sleep(0). Посмотреть изменения в порядке вывода.
 
Закоментировать Sleep() и установить приоритеты потокам. Посмотреть изменения в порядке вывода.
 
Закоментировать Sleep() и установить приоритеты потокам. Посмотреть изменения в порядке вывода.
  
13.2. Написать программу, демонстрирующую работу Join(): основной поток должен дожидаться окончания работы (не менее) 2-х потоков, потом продолжать работу. Конструктивно: дополнительные потоки должны предоставлять данные, необходимые для дальнейшей работы основного потока.
+
15.2. Написать программу, демонстрирующую работу t.Join(): основной поток должен дожидаться окончания работы 2-х потоков, потом продолжать работу. Конструктивно: дополнительные потоки должны предоставлять данные, необходимые для дальнейшей работы основного потока.
 +
 
 +
15.3. Продемонстрировать работу критических секций на примере банкомата.
 +
 
 +
15.4. Используя критические секции, реализовать потокобезопасный класс Стек. Операции Push и Pop должны блокироваться одним объектом. Проиллюстрировать корректность работы стека, выполняя операции Push и Pop случайным образом в разных потоках. Продемонстрировать, что обычный класс стека не является потокобезопасным.
 +
 
 +
15.5. Продемонстрировать ситуацию с возникновением DeadLock.
 +
 
 +
====Задание 16 на пул потоков и синхронизацию====
 +
 
 +
16.1. Продемонстрировать асинхронную работу методов с использованием пула потоков (Task.Run). Операции для пула потоков должны быть достаточно длительными.
 +
 
 +
16.2. Продемонстрировать выполнение асинхронных операций, используя:
 +
 
 +
:а) модель ожидания
  
* 13.3. Продемонстрировать работу критических секций на примере банкомата.
+
:б) модель опроса
  
13.4. Используя критические секции, реализовать потокобезопасный класс Стек. Операции Push и Pop должны блокироваться одним объектом. Проиллюстрировать корректность работы стека, выполняя операции Push и Pop случайным образом в разных потоках. Продемонстрировать, что обычный класс стека не является потокобезопасным.
+
:в) модель с обратным вызовом
  
13.5. Продемонстрировать ситуацию с возникновением DeadLock.
+
:г) модель с продолжением (continuation)
  
* 13.6. Продемонстрировать работу Monitor'ов (Monitor.Wait, Monitor.Pulse, Monitor.PulseAll). Продемонстрировать отличия Monitor.Pulse и Monitor.PulseAll. Проверить работу Monitor.Wait, Monitor.Pulse для работы с очередью посетителей (один поток генерирует клиентов через разные промежутки времени, второй их обслуживает)
+
====Задание 17 на асинхронное программирование====
  
====Задание 14 на асинхронное программирование====
+
//17.1. Продемонстрировать работу async и await
  
14.1. Продемонстрировать асинхронную работу методов с использованием пула потоков. Операции для пула потоков должны быть достаточно длительными.
+
17.2а) Продемонстрировать работу именованного мьютекса для синхронизации действий между несколькими процессами.
  
14.) Продемонстрировать работу именованного семафора для синхронизации действий между несколькими процессами.
+
17.) Продемонстрировать работу семафора для синхронизации действий внутри одного процесса.
  
14.) Продемонстрировать работу именованного мьютекса для синхронизации действий между несколькими процессами.
+
17.) Продемонстрировать работу ManualResetEvent в ситуации когда несколько потоков дожидаются возникновения события.
  
* 14.) Продемонстрировать работу ManualResetEvent в ситуации когда несколько потоков дожидаются возникновения события.
+
17.) Продемонстрировать работу AutoResetEvent в ситуации когда несколько потоков работают, попеременно посылая друг другу команды на продолжение.
  
14.3. Продемонстрировать выполнение асинхронных вычислительных операций с использованием методов BeginInvoke и EndInvoke для делегатов.
 
  
* 14.4. Продемонстрировать выполнение асинхронных операций ввода-вывода для задачи чтения из большого файла, используя:
+
-------------
  
* :а) модель ожидания
+
-------------
  
* :б) модель опроса
+
-------------
  
* :в) модель с обратным вызовом
+
[[Старые задания по курсу "Платформа .NET"]]

Текущая версия на 17:14, 7 сентября 2021

К основной странице курса


Практические задания по курсу "Язык C# и платформа .NET"

Материалы к заданию 1

Задания к зачету

Задание 1 (Занятие 1)

1.1. Откомпилировать простейшую библиотеку .dll с функцией, складывающей два числа, и простейшую программу .exe, вызывающую этот метод библиотеки, с помощью csc.exe. Записать размер полученных файлов.

1.2. Просмотреть метаданные в сборках .dll и .exe с помощью ILDasm и с помощью ILSpy

1.2a. Создать простейшее оконное приложение и записать его размер.

using System;
using System.Windows.Forms;
class MainWin: Form 
{
  static void Main() 
  {
    Application.Run(new MainWin());
  }
}

1.3. Написать dll на PascalABC.NET, содержащую функцию add, складывающую 2 числа. Просмотреть метаданные с помощью ildasm или ILSpy (скачать ILSpy из Интернета) и вызвать функцию add из PascalABC.NET-dll в программе на C#

1.4. Вызвать метод из dll, написанной на C#, в программе на PascalABC.NET

Для подключения dll в PascalABC.NET используйте следующий синтаксис:

{$reference my.dll}
...

1.5. Вызвать метод из dll, написанной на PascalABC.NET, в программе на C#

Для написания dll на PascalABC.NET используйте следующий синтаксис:

library mylib;

function f(a,b: integer) := a + b;

end.

1.6. Откомпилировать сборки exe и dll с помощью Visual Studio в режимах Debug и Release. Сравнить размеры полученных файлов.

Задание 1б (Занятие 2)

1.7. Сравнить скорость работы вычислительного алгоритма на языках C#, C++, Java, PascalABC.NET, Python

a) Сумма(i=1..n)(1/(i*j)), n - достаточно большое
б) Сумма(i=1..n)(1/(a[i]*a[j])), n - достаточно большое
в) Произведение квадратных матриц n x n, n - достаточно большое

Таблица сравнения скорости для группы 4.1

Для замера времени в PascalABC.NET воспользоваться функцией Milliseconds, возвращающей время с начала работы программы в секундах. В настройках отключить режим Debug и запускать программу по Shift-F9.

Для PascalABC.NET в настройках опций компиляции отключить "Генерировать отладочную информацию" и "Удалять exe после выполнения". Для компиляции программы воспользоваться командой Компилировать (Ctrl-F9) и запускать exe файл вне среды, либо запускать по Shift-F9 в режиме без связи с оболочкой.

Занести все данные по скорости в таблицу

В пунктах б) и в) заполнить массив a и матрицы случайными числами в диапазоне от 1 до 1.1. Для генерации случайных чисел в .NET пользоваться классом Random:

Random r = new Random();
r.NextDouble();

Сравнивать скорость в Debug и Release - конфигурациях.

Для .NET-языков сравнить IL-код для циклов с помощью ildasm и выявить неэффективность генерации кода.

Задание 2 на наследование и полиморфизм (Занятие 3)

2.1. Создать иерархию классов Person-Student-Teacher. Каждый класс – в своей сборке. В каждом классе должны быть свойства, а также виртуальная функция Print и переопределенная функция ToString(). Основная программа создает массив объектов Person или их наследников, после чего выдает его на экран. У каждого Teacher должен быть список Students, которыми он руководит, у каждого Student - Teacher, который им руководит.

Замечание. В процессе реализации возникнет такая ошибка как циклическая зависимость сборок: сборка Student зависит от сборки Teacher и наоборот. Для устранения этой ошибки рекомендуется создать класс Student без поля Teacher, после чего создать производный класс StudentWithAdvisor с полем Teacher в отдельной сборке.

2.2. Для классов Person-Student-Teacher реализовать и оттестировать ToString(), Equals(), GetHashCode().

2.3. Для классов Person-Student-Teacher реализовать статические методы RandomPerson, RandomStudent, RandomTeacher, которые возвращают случайного из некоторого статического массива.

2.4. С помощью is, as, GetType определить, сколько в массиве персон, студентов и преподавателей и перевести всех студентов на следующий курс.

2.5. Для классов Person-Student-Teacher реализовать глубокое клонирование, определив виртуальный метод Clone(). Клон должен возвращать точную копию по значению и типу. Проиллюстрировать Clone на примере контейнера персон - должны создаваться клоны объекты ровно тех типов, которые содержатся в исходном контейнере.

(нет) 2.6. Используя метод GetType() класса Student и метод BaseType() класса Type, вывести всех предков класса Student (написать общий метод)


Замечание 1. Свойства ("умные" поля) определяются так:

private int age;
public int Age {
  get { return age; }
  set { if (value<0) value = 0; age = value; }
}

Здесь value - переменная, неявно объявленная в каждом сеттере. Свойства отличаются от полей тем, что при доступе на чтение и запись можно совершать дополнительные действия. Обычная практика - проверка в сеттере значения на допустимость и его исправление или генерация исключения.

Замечание 2. В конструкторе потомка следует вызывать конструктор предка в списке инициализации:

Student(...): base(...) {}

Замечание 3. Виртуальные функции следует объявлять с ключевым словом virtual в предке и с ключевым словом override в потомках. Виртуальную функцию следует вызывать через переменную базового класса:

Person p = new Student(...);
p.Print();

Замечание 4. Функции ToString() и Equals() определены в базовом классе Object как виртуальные.

Замечание 5. p is Student возвращает True если в p - студент или производный класс. p as Student преобразует тип p к Student, а если это невозможно, возвращает null.

Замечание 6. Для сравнения на точное совпадение типа используется GetType: if (p.GetType()==typeof(Student))

Задание 3 на перегрузку операторов

3.0. Для классов Person-Student-Teacher реализовать ==, !=

3.1. Создать класс Frac с перегруженными операциями + - * / , а также с возможностью приведения типа Frac->double. Должны быть реализованы также ToString(), Equals(), ==, !=. Вычислить значение полинома в точке. Все коэффициенты и x должны иметь тип Frac. Сравнить производительность в случае реализации Frac как класса и как структуры.

Таблица сравнения скорости Frac (см. лист 2)

3.2. Создать структуру Complex с перегруженными операциями, а также с возможностью приведения типа double->complex. Должны быть реализованы также ToString(), Equals(), ==, !=. Сравнить производительность в случае реализации Complex как класса и как структуры.

//3.3. Используя класс Frac, реализовать метод Гаусса для решения системы линейных уравнений из n уравнений с n неизвестными и с рациональными коэффициентами, заданными типом Frac. Найти точное решение, представляющее собой List<Frac>.

Замечание 1. Операции реализуются как статические методы:

 public static bool operator==(Person p1, Person p2) {return p1.Equals(p2);}

Замечание 2. Операции приведения типа определяются так:

public static explicit operator double(Frac f) {...}

explicit означает явное приведение типа, вместо него может стоять implicit - неявное приведение типа.

Задание 4 на индексаторы

4.1. Создать класс, реализующий битовый массив на основе обычного, используя индексные свойства.

4.2. Создать класс ассоциативного массива, используя два списка List - список ключей и список значений. Основная операция: x = d[K] (на чтение) и d[K] = V (на запись)

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

private Dictionary<string,int> a;
public int this[string s] {
  get { return a[s]; }
  set { a[s] = value; }
}

Задание 5 на интерфейсы

5.1. Проверить, как работает явная и неявная реализация методов интерфейса. Для этого явно реализовать в классах Person и Student интерфейс

interface IPrintable {
  void Print();
}

и вызвать этот метод, используя переменную типа интерфейс. Заметим, что старый метод Print также можно оставить.

5.2. В классе Student реализовать интерфейс IComparable<Student>. Воспользовавшись Array.Sort, отсортировать массив студентов.

5.3. Реализовать интерфейс IComparer<Student> в классе StudentComparer, вложенном в Student. Параметром его конструктора должен выступать критерий сортировки. Реализовать в классе Student несколько статических свойств по количеству критериев сортировки (например, Student.SortByGroup). Воспользовавшись второй формой Array.Sort, отсортировать массив студентов по разным критериям.

5.4. Реализовать в классах Person-Student-Teacher интерфейс ICloneable и проиллюстрировать его использование.

5.5. Реализовать в классе Person интерфейс IDisposable и убедиться в корректности его работы в операторе using

Интерфейс IDisposable имеет вид:

interface IDisposable {
  void Dispose();
}

Он используется для детерминированного освобождения ресурсов в стиле C++, метод Dispose играет роль деструктора. Если класс My поддерживает интерфейс IDisposable, то его можно использовать в операторе using:

using (My m = new My())
{

} // в конце гарантированно вызовется Dispose

В методе Dispose() класса Person достаточно выдавать диагностическое сообщение о том, что метод Dispose() вызван.

5.6. Создать контейнер Persons, который можно было бы использовать в foreach. Для этого поместить в него поле List<Person> list и метод Add(Person p), а также реализовать интерфейс IEnumerable<Person>, используя в методе GetEnumerator конструкцию yield return.

Пример реализации:

    public class CustomContainer: IEnumerable<int>
    {
        public IEnumerator<int> GetEnumerator()
        {
            for (int i = 0; i < 10; i++)
                yield return i;
        }
        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    }

Заполнить контейнер Persons персонами и студентами, используя его метод Add. После этого воспользоваться методом foreach по данному контейнеру, выдавая всех персон и студентов в контейнере. Перед каждой персоной или студентом должен выводиться порядковый номер во внутреннем списке.


5.7. Реализовать обобщенную функцию MinIndex, возвращающую пару (индекс, МинимальныйЭлемент) в массиве элементов типа T. Для этого наложить в секции where ограничений на параметры обобщения условие where T: IComparable<T>. Результат возвращать в виде Tuple<int,T>. Если в массиве нет элементов, то индекс минимального равен -1, а минимальный равен default(T) - значению по умолчанию для типа T.

Задание 6 на yield

6.1. Используя yield, реализовать и оттестировать метод расширения - генератор n членов арифметической прогрессии с первым элементом a0 и шагом d. Для вывода реализовать метод Print, использующий yield и выводящий любую последовательность.

6.2. Реализовать метод-генератор бесконечной последовательности значений val. Для тестирования реализовать метод

 IEnumerable<T> TakeN<T>(this IEnumerable<T> seq, int n)

который возвращает n первых членов бесконечной последовательности.

6.3. Реализовать метод - генератор бесконечной последовательности случайных чисел.

6.4. Реализовать метод - генератор бесконечной арифметической прогрессии.

6.4а. Реализовать метод - генератор бесконечной последовательности чисел Фибоначчи.

6.5. Реализовать метод расширения - генератор бесконечной последовательности циклически повторяющихся элементов последовательности seq

6.6. Реализовать метод расширения, принимающий две последовательности одинаковой длины и возвращающий последовательность пар в виде Tuple<T,T1>

6.7. Реализовать метод расширения, возвращающий по последовательности целых отфильтрованную последовательность, состоящую только из четных элементов исходной последовательности, только из элементов исходной последовательности, удовлетворяющей определенному условию

6.8. Реализовать метод расширения, возвращающий по последовательности целых значений преобразованную последовательность квадратов этих значений (последовательность, полученную произвольной функцией преобразования).

6.9. Реализовать метод расширения, принимающий две последовательности элементов одного типа и возвращающий последовательность чередующихся элементов исходных последовательностей

6.10. Реализовать метод расширения, возвращающий по последовательности значений последовательность пар рядом стоящих значений:

 1 2 3 4 5  ->   (1,2) (2,3) (3,4) (4,5)

Задание 8 на LINQ

LINQ to Objects (автор М.Э.Абрамян)

LINQ. Выражения запросов (автор М.Э.Абрамян)

Как в дисплейном классе настроить папку для решения заданий LinqBegin из электронного задачника Programming Taskbook

1. Создать на своем диске папку LINQ

2. Установить PTForLinq отсюда

3. Скопировать в свою папку следующие файлы:

Load.lnk
results.dat

4. Запустить ярлык Load.lnk, правой мышью выбрать среду Visual Studio

5. Набрать имя выполняемого задания LinqBegin1, LinqBegin2 и т.д., нажать Enter и проигнорировать вопрос, появляющийся при открытии проекта с заданием в VS.

Пример решения LinqBegin1
public static void Solve()
{
  Task("LinqBegin1");
  var seq = GetEnumerableInt();
  Put(seq.First(x => x > 0));
  Put(seq.Last(x => x < 0));
}
Задания из электронного задачника для выполнения

Все задания LinqBegin и LinqObjects (М.Э.Абрамян)

Занятие 1 по LINQ
  1. LinqBegin1-2,5-7
Занятие 2 по LINQ
  1. LinqBegin21,24,25,27,28,29,31,34,35,36,39,40
Занятие 3 по LINQ
  1. LinqBegin44,46,48,50,52,53,56,58,60

Задание 9 на LINQObject

Индивидуальные задания по LinqObj
Авилов Арсений        5  22  42  56  77  91
Алёхина Диана         6  23  35  55  76  92
Арутюнов Баграт       12 29  41  49  70  87
Боброва Елена         7  16  33  45  77  93
Будаева Екатерина     10 27  38  51  72  89
Деменский Владислав   4  21  37  57  78  83
Дудников Алексей      13 30  39  48  69  88
Жаров Глеб            11 28  40  50  71  86
Иноземцев Эдуард      8  18  44  60  79  94
Какурин Никита        7  24  34  54  75  85
Козак Михаил          3  20  32  58  79  84 
Кормиленко Алексей    1  26  43  59  78  92
Лунёв Илья            9  19  37  62  72  95
Мухина Виктория       2  15  32  46  71  91
Осипян Рубен          14 17  33  47  80  90
Пономаренко Сергей    9  16  36  52  73  82
Резник Владислав      14 29  43  61  70  96
Самгин Роман          8  25  31  53  74  81
Сухов Виктор          10 30  44  63  71  97
Тадевосян Эдгар       11 21  35  64  72  98
Тихонов Алексей       1  19  32  47  80  96
Фазилов Алишер        2  20  43  62  71  90
Царик Максимилиан     3  18  46  60  80  91
Черненко Глеб         4  24  43  48  75  85
Шевелёва Александра   5  25  44  54  76  88
Югай Кристина         6  21  45  55  77  89 
Яблочкин Иван         7  22  47  57  78  93


    14 17  33  47  80  90
    9  16  36  52  73  82  17.1   10.2   3.1
    14 29  43  61  70  96  17.2а  6.7    5.3
    8  25  31  53  74  81.  16.2в.  12.1.  6.5
      
    10 30  44  63  71  97  16.2б  13.3   5.3
    11 21  35  64  72  98  16.2в. 12.1.  6.5

Задание 10 на файлы и потоки

Презентация по файлам


10.1. Сохранить в текстовых файлах русско-английский тест в различных кодировках и затем считать его из этого файла:

а) в однобайтовых: MS DOS, Koi-8, Windows

б) в Unicode: Utf-8, Utf-16

10.2. Дан текстовый файл. Удалить из него последние 5 строк.

10.3. В текстовом файле записаны вещественные числа (на каждой строчке - несколько, разделены несколькими пробелами, в формате 3.14 2.597) и другие лексемы (не числа). Найти сумму чисел, игнорируя неверные лексемы.

10.4. Создать типизированный файл целых, затем модифицировать его, возведя все элементы в квадрат.

10.5. Для данной папки рекурсивно выдать список её файлов и подпапок.

Задание 11 на сериализацию

Для выполнения заданий следует подключить к основной сборке следующие сборки: System.Runtime.Serialization System.Runtime.Serialization.Formatters.Soap

11.1. Используя BinaryFormatter и атрибут [Serializable], сериализовать на диск в бинарном формате объекты классов Student и Teacher, после чего десериализовать. Убедиться, что сериализация работает корректно (для этого десериализовать и вывести на экран повторно). Обратить особое внимание, что класс Teacher содержит поле List<Student>. Попробовать провести сериализацию, используя SoapFormatter. Что не работает? Как это можно исправить (какое поле убрать/не сериализовать)?

11.2. Используя SoapFormatter и атрибут [Serializable], сериализовать на диск в XML формате связный список из нескольких

 class Node
 {
   public int data;
   public Node next; 
 // конструктор
 }

Затем десериализовать его и убедиться, что все данные сохранились. Посмотреть содержимое XML-файла и понять, за счет чего десериализуется связный список (как восстанавливаются ссылки). Можно ли в этом случае использовать BinaryFormatter?

11.3. Используя класс XMLSerializer, сериализовать-десериализовать объекты класса Student в XML-формате. Использовать атрибуты [XmlAttribute] для полей, которые необходимо сериализовать. Чем отличается XML-представление от SoapFormatter? Понять ограничения этого сериализатора.

11.4. Используя SoapFormatter, создать структуру, поддерживающую граф объектов и сериализовать-десериализовать граф. Подумать над представлением графа в виде списка инцидентных вершин, не используя List<T>.

11.5. Используя DataContractSerializer, его методы ReadObject и WriteObject и атрибуты [DataContract] для класса и [DataMember] для открытых полей или свойств, сериализовать на диск в XML-формате объекты класса Student. Вызвав конструктор DataContractSerializer в виде new DataContractSerializer (typeof (Student), new Type[ ]{typeof (SeniorStudent)}), сериализовать-десериализовать также потомков Student типа SeniorStudent.

Задание 12 на рефлексию

12.1. Используя механизм отражения, "расшифровать" все классы, содержащиеся в Student.dll. Создать объект класса Student, вызвать его метод, свойство (на чтение и запись). dll не подключать к проекту статически, использовать Assembly.LoadFrom().

12.2. Для данного типа (Student) вывести цепочку всех его предков и все интерфейсы, им реализуемые.

12.3. Используя механизм отражения, динамически создать объект класса Dictionary<string,int>, динамически наполнить его несколькими значениями и динамически вызвать метод (свойство), возвращающее значение по ключу.

12.4. Создать программу автоподключения плагинов к программе. Плагин представляет собой dll, содержащую класс, удовлетворяющий некоторому интерфейсу с одним методом. Все плагины бросаются в папку с основной программой. Программа должна анализировать все классы в dll в текущей папке, отбирать те, которые реализуют интерфейс, создавать по одному объекту каждого такого класса и вызывать метод интерфейса для этого объекта.

#Задание 13 на Reflection.Emit

13.1. Создайте и вызовите динамический метод, вычисляющий 2018*2018

13.2. Создайте и вызовите динамический метод, выполняющий следующий код:

var x = 2.0;
var p = Math.Sqrt(x+2);
Console.WriteLine(p);

13.3. Создайте и вызовите динамический метод, выполняющий следующий код:

var p = 1;
while (p<=2048)
{
  Console.WriteLine(p);
  p *= 2;
}

13.4. Сгенерируйте код для программы, выводящей последовательность 20 первых чисел Фибоначчи.

13.5. Сгенерируйте код для программы, вычисляющей сумму ряда sum(i=1..n,1.0/i). Сравните программу по производительности с аналогичной программой на C#

Задание 15 на потоки (Threads)

Материалы по параллельному программированию в .NET на MSDN

15.1. Создать несколько потоков, выводящих на консоль в цикле свой hashcode. Посмотреть порядок вывода. Добавить Sleep(1), Sleep(10), Sleep(0). Посмотреть изменения в порядке вывода. Закоментировать Sleep() и установить приоритеты потокам. Посмотреть изменения в порядке вывода.

15.2. Написать программу, демонстрирующую работу t.Join(): основной поток должен дожидаться окончания работы 2-х потоков, потом продолжать работу. Конструктивно: дополнительные потоки должны предоставлять данные, необходимые для дальнейшей работы основного потока.

15.3. Продемонстрировать работу критических секций на примере банкомата.

15.4. Используя критические секции, реализовать потокобезопасный класс Стек. Операции Push и Pop должны блокироваться одним объектом. Проиллюстрировать корректность работы стека, выполняя операции Push и Pop случайным образом в разных потоках. Продемонстрировать, что обычный класс стека не является потокобезопасным.

15.5. Продемонстрировать ситуацию с возникновением DeadLock.

Задание 16 на пул потоков и синхронизацию

16.1. Продемонстрировать асинхронную работу методов с использованием пула потоков (Task.Run). Операции для пула потоков должны быть достаточно длительными.

16.2. Продемонстрировать выполнение асинхронных операций, используя:

а) модель ожидания
б) модель опроса
в) модель с обратным вызовом
г) модель с продолжением (continuation)

Задание 17 на асинхронное программирование

//17.1. Продемонстрировать работу async и await

17.2а) Продемонстрировать работу именованного мьютекса для синхронизации действий между несколькими процессами.

17.2б) Продемонстрировать работу семафора для синхронизации действий внутри одного процесса.

17.2в) Продемонстрировать работу ManualResetEvent в ситуации когда несколько потоков дожидаются возникновения события.

17.2г) Продемонстрировать работу AutoResetEvent в ситуации когда несколько потоков работают, попеременно посылая друг другу команды на продолжение.





Старые задания по курсу "Платформа .NET"