Назад Уперед Зміст


ЗАВДАННЯ ДЛЯ СТУДЕНТІВ, ЗНАЙОМИХ З С #

ПРИКЛАД ЗАВДАНЬ

Завдання 1 (Класи, властивості, індексатори. Одномірні, прямокутні і ступінчасті масиви)

Вимоги до програми, загальні для всіх варіантів

  1. Визначити клас Person, який має
  2. У класі Person визначити конструктори:
  3. У класі Person визначити властивості c методами get та set:
  4. У класі Person визначити
  5. Для цього в методі Main () створити

Тип елементів масивів залежить від варіанту роботи. Масиви повинні мати однакове число елементів. Якщо число рядків в двовимірному прямокутному масиві одно nrow, а число стовпців ncolumn, то одновимірний масив повинен містити nrow * ncolumn елементів, в двовимірному ступеневу масиві загальне число елементів також має дорівнювати nrow * ncolumn.

Значення nrow і ncolumn вводяться в процесі роботи програми у вигляді одного рядка з роздільниками. У запрошенні, яке отримує користувач, повинна бути інформація про те, які символи можна використовувати як роздільники, число роздільників повинно бути більше 1. За допомогою методу Split класу System.String додаток розбирає введену користувачем текстовий рядок з інформацією про кількість рядків і числі стовпців двовимірного масиву і привласнює значення змінним, які містять значення nrow і ncolumn. У першій лабораторній роботі не потрібно обробляти помилки введення, передбачається, що користувач правильно ввів дані. Додаток розподіляє пам'ять для всіх масивів і ініціалізує елементи масивів. Для ініціалізації елементів можна використовувати конструктор без параметрів.

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

Для вимірювання часу виконання операцій можна використовувати властивість Environment.TickCount. Cтатіческое властивість TickCount класу Environment має тип int, використовує інформацію системного таймера і містить час в мілісекундах, який минув з моменту перезавантаження комп'ютера. Щоб отримати час виконання деякого блоку коду, необхідно викликати Environment.TickCount безпосередньо перед блоком і відразу ж після останнього оператора блоку і взяти різницю значень.

В блоці коду, для якого вимірюється час, не повинно бути операцій розподілу пам'яті для масивів, ініціалізації елементів масивів і операцій виведення даних на консоль. Блоки коду повинні містити тільки операції з елементами масиву. Попередньо обчислені значення часу виконання операцій для трьох типів масивів, а також число рядків nrow і стовпців ncolumn виводяться на консоль. Висновок повинен бути підписаний, тобто висновок повинен містити інформацію про те, якого типу масиву відповідає виведене значення. ?

ПРИКЛАД ВАРІАНТУ ЗАВДАННЯ ТА ЇЇ РЕАЛІЗАЦІЇ

Варіант завдання. Вимоги до програми

  1. Визначити тип Education - перерахування (enum) зі значеннями Specialist, Вachelor, SecondEducation.
  2. Визначити клас Exam, який має три відкритих автореалізуемих властивості, доступних для читання і запису:
  3. Визначити клас Student, який має
  4. У класі Student визначити конструктори:
  5. У класі Student визначити властивості c методами get та set:
  6. У класі Student визначити
  7. У методі Main ()
    1. Створити один об'єкт типу Student, перетворити дані в текстовий вигляд за допомогою методу ToShortString () і вивести дані.
    2. Вивести значення індексатора для значень індексу Education.Specialist, Education.Bachelor і Education.SecondEducation.
    3. Присвоїти значення всіма визначеними в типі Student властивостями, перетворити дані в текстовий вигляд за допомогою методу ToString () і вивести дані.
    4. C допомогою методу AddExams (params Exam []) додати елементи в список іспитів і вивести дані об'єкта Student, використовуючи метод ToString ().
    5. Порівняти час виконання операцій з елементами одновимірного, двовимірного прямокутного і двовимірного ступеневої масивів з однаковим числом елементів типу Exam.

Проект. Консольний додаток

Створюємо проект csharptrain.Определяем тип Education - перерахування (enum) зі значеннями Specialist, Вachelor, SecondEducation. Додаємо перед класом programm перерахування:

enum Education
    {
        Specialist,
        Bachelor,
        SecondEducation
    }
 

Визначаємо клас Exam, який має три відкритих автореалізуемих властивості, доступних для читання і запису:

    class Student : Person
    {
        public Education Education { get; set; }
        private int GroupId = -1;
        private int GroupID
        {
            get
            {
                return GroupId;
            }
            set
            {
                if (value <= 100 || value > 599)
                    throw new Exception("Incorrect group ID! Correct groupID range is [101-599]");
                GroupId = value;
            }
        }
        public Exam[] Exams; //Intentionally left public to perform faster testing
        private List Tests;
        public double AverageMark
        {
            get
            {
                return Exams.Sum((x) => x.Mark) / Exams.Length;
            }
        }
        public Person Person
        {
            get
            {
                return new Person(base.Name, base.Age, base.Date);
            }
            set
            {
                Date = value.Date;
                Age = value.Age;
                Name = value.Name;
            }
        }
        public Exam[] getExams
        {
            get
            {
                Exam[] ExamsCopy = new Exam[Exams.Length];
                Array.Copy(Exams, ExamsCopy, Exams.Length);
                return ExamsCopy;
            }
            set
            {
                Array.Copy(value, Exams, value.Length);
            }
        }
        
        
        /// Конструктор класса student с параметрами Person person,Education Education, int GroupID
       
        public Student(Person person, Education Education, int GroupID)
            : base(person)
        {
            this.Education = Education;
            this.GroupID = GroupID;
            Exams = new Exam[0];
            Tests = new List();
        }
       
        /// Конструктор класса Student без параметров

        public Student()
            : base()
        {
            Education = Education.Bachelor;
            GroupID = 101;
            Exams = new Exam[0];
            Tests = new List();
        }
        public bool this[Education Education]
        {
            get { return Education == this.Education; }
        }
  
        /// Добавляет экзамены студенту
        /// Массив экзаменов, которые нужо добавить 
        public void AddExams(Exam[] exams)
        {
            Exams = Exams.Concat(exams).ToArray();
            Exam[] tmp = new Exam[Exams.Length];
        }
       
        /// Добавляет зачеты студенту
      
        public void AddTests(Test[] tests)
        {
            Tests.AddRange(tests);
        }
        public override string ToString()
        {
            return "Student : " + Name + "\tEducation : " + Education + "\tGroupID : " + GroupID.ToString()
                + MyUtilits.Sum(Exams, (x) => { return Environment.NewLine + x.ToString(); });
        }
        public string ToShortString()
        {
            return "Student : " /*+ StudentData.ToString()*/ + "\tEducation :" + Education + "\tGroupID :" + GroupID.ToString()
                + "\tAvg. Mark : " + AverageMark.ToString();
        }
    }

Тестуємо проект, для цього в методі Main ()

  1. Створюємо один об'єкт типу Student, щоб перетворити дані в текстовий вигляд за допомогою методу ToShortString () і виводимо дані.
  2. Виводимо значення індексатора для значень індексу Education.Specialist, Education.Bachelor і Education.SecondEducation.
  3. Надаємо значення всіма визначеними в типі Student властивостями, перетворимо дані в текстовий вигляд за допомогою методу ToString () і виводимо дані.
  4. C допомогою методу AddExams (params Exam []) додаємо елементи в список іспитів і виводимо дані об'єкта Student, використовуючи метод ToString ().
  5. Порівнюємо час виконання операцій з елементами одновимірного, двовимірного прямокутного і двовимірного ступеневої масивів з однаковим числом елементів типу Exam.

Клас Test, що задає уявлення заліку в цій програмі


    /// Клас, що задає уявлення заліку в цій програмі
     
    /// Клас, що задає об'єктне уявлення іспиту в даній програмі
    
    class Exam
    {
        public string SubjectName;
        public int Mark {get; set; }
        public DateTime Date {get; set; }
        /// 
        /// Конструктор з параметрами класу Exam
        /// 
        public Exam (string SubjectName, int Mark, DateTime DateOfExam)
        {
            this.SubjectName = SubjectName;
            this.Mark = Mark;
            Date = DateOfExam;
        }
        /// 
        /// Конструктор без параметрів класу Exam
        /// 
        public Exam ()
        {
            SubjectName = "Computer Logic";
            Mark = 5;
            Date = new DateTime (2016, 6, 15, 12, 0, 0);
        }
        public override string ToString ()
        {
            return "Exam:" + SubjectName + "\ tMark:" + Mark.ToString () + "\ tDate:" + Date.ToString ( "h: mm d-MM-yyyy");
        }
      
  }

Визначається клас Student, який має

  1. У класі Student визначити конструктори:
  2. У класі Student визначити властивості c методами get та set:
  3. У класі Student визначити
    
    /// Клас забезпечує об'єктне уявлення властивостей студента, а також простий доступ до них.
  
    class Test
    {
        public string SubjectName;
        public bool Closed { get; set; }
        public Test(bool Closed = true, string SubjectName = "Maths")
        {
            this.Closed = Closed;
            this.SubjectName = SubjectName;
        }
        public override string ToString()
        {
            return SubjectName + " : " + Closed.ToString();
        }
    }

    static void Main(string[] args)
        {
            Person p1 = new Person("Valeriy", 18, new DateTime(1998, 3, 3));
            Person p2 = new Person("Valeriy", 18, new DateTime(1998, 3, 3));
            System.Console.Out.WriteLine(object.ReferenceEquals(p1, p2).ToString() + " " + p1.Equals(p2).ToString());

            Student student = new Student(p1, Education.Bachelor, 101);
            Exam[] exams = new Exam[4];
            exams[0] = new Exam("Linear Math", 5, new DateTime(2016, 12, 23, 12, 0, 0));
            exams[1] = new Exam("Algorithms", 5, new DateTime(2016, 11, 23, 12, 0, 0));
            exams[2] = new Exam("Math Analysis", 3, new DateTime(2016, 10, 23, 12, 0, 0));
            exams[3] = new Exam("Discrete Maths", 4, new DateTime(2016, 10, 23, 12, 0, 0));
            student.AddExams(exams);
            Test[] tests = new Test[4];
            tests[0] = new Test(true, "Computer logics");
            tests[1] = new Test(true, "Linear Maths");
            tests[2] = new Test(false, "Math Analysis");
            tests[3] = new Test(true, "Discrete Maths");
            student.AddTests(tests);

            System.Console.Out.WriteLine(student.Person);
            System.Console.Out.WriteLine(student.ToString());
          
        }

Результат.  

Завдання 2.Наследованіе. Винятки. Інтерфейси. Ітератори і блоки ітераторів

Інформація для всіх варіантів

  1. У класі Person з завдання 1 і в класах, додатково зазначених у варіантах, треба
  2. Реалізація віртуального методу bool Equals (object obj) в класі System.Object визначає рівність об'єктів як рівність посилань на об'єкти. Деякі класи з базової бібліотеки BCL скасовують метод Equals (). У класі System.String цей метод перевизначений так, що рівними вважаються рядки, які збігаються посимвольний. Реалізація методу Equals () в структурному типі DateTime рівність об'єктів DateTime визначає як рівність значень.
  3. У задачі потрібно перевизначити метод Equals так, щоб об'єкти вважалися рівними, якщо рівні всі дані об'єктів. Для класу Person це означає, що рівні дати народження і посимвольний збігаються рядки з ім'ям і прізвищем.
  4. Визначення операцій == і! = Повинно бути погоджено з перевизначення методом Equals, тобто критерії, за якими перевіряється рівність об'єктів в методі Equals, повинні використовуватися і при перевірці рівності об'єктів в операціях == і! =.

    Перевизначення віртуального методу int GetHashCode () також має бути узгоджено з операціями == і! =. Віртуальний метод GetHashCode () використовується деякими класами базової бібліотеки, наприклад, колекціями-словниками. Класи базової бібліотеки, що викликають метод GetHashCode () з призначеного для користувача типу, припускають, що рівним об'єктів відповідають рівні значення хеш-кодів. Тому в разі, коли під рівністю об'єктів розуміється збіг даних (а не посилань), реалізація методу GetHashCode () повинна для об'єктів з однаковими даними повертати рівні значення хеш-кодів.

  5. У класах, зазначених у варіантах роботи, потрібно визначити метод object DeepCopy () для створення повної копії об'єкта. Певні в деяких класах базової бібліотеки методи Clone () і Copy () створюють обмежену (shallow) копію об'єкта - при копіюванні об'єкта копії створюються тільки для полів структурних типів, для полів посилальних типів копіюються тільки посилання. В результаті в обмеженою копії об'єкта поля-посилання вказують на ті ж об'єкти, що і в вихідному об'єкті. Метод DeepCopy () повинен створити повні копії всіх об'єктів, посилання на які містять поля типу. Після створення повна копія не залежить від вихідного об'єкта - зміна будь-якого поля або властивості вихідного об'єкта не повинна приводити до зміни копії. При реалізації методу DeepCopy () в класі, який має поле типу System.Collections.ArrayList, слід мати на увазі, що певні в класі ArrayList конструктор ArrayList (ICollection) і метод Clone () при створенні копії колекції, що складається з елементів посилальних типів, копіюють тільки посилання.
  6. Метод DeepCopy () повинен створити як копії елементів колекції ArrayList, так і повні копії об'єктів, на які посилаються елементи колекції. Для типів, що містять колекції, реалізація методу DeepCopy () спрощується, якщо в типах елементів колекцій також визначити метод DeepCopy ().

Завдання 3. Делегати. Події

Інформація для всіх варіантів

В задаче3 потрібно визначити клас, що містить типізовану колекцію, який за допомогою подій сповіщає про зміни в колекції.

Колекція складається з об'єктів посилальних типів. Колекція змінюється при видаленні / додаванні елементів або при зміні однієї з вхідних в колекцію посилань, наприклад, коли однією з посилань присвоюється нове значення. В цьому випадку у відповідних методах або властивості класу кидаються події.

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

Для подій, що сповіщають про зміни в колекції, визначається свій делегат. Події реєструються в спеціальних класах-слухачах.

Варіант завдання.

Вимоги до програми

  1. Визначити клас StudentCollection, яка за допомогою подій повідомляє про зміни в колекції.
  2. Для подій визначити делегат StudentListHandler з сигнатурою:

    void StudentListHandler (object source, StudentListHandlerEventArgs args);

  3. Клас StudentListHandlerEventArgs, похідний від класу System.EventArgs, містить
  4. У нову версію класу StudentCollection додати
  5. У нову версію класу StudentCollection додати дві події типу StudentListHandler

Приклад реалізації проекту (всі три завдання)

Створюється інтерфейс для класів, які містять дату і метод повного копіювання,  причому всі дочірні об'єкти нового класу не були б посиланнями на дочірні об'єкти копійованого класу.

В темі 5 (а саме в 5.7) розглядалися два стандартних інтерфейсу, зараз розглянемо ще два IEnumerable, IEnumerator. Напевно було б досить зручно звертатися до внутрішніх об'єктів, використовуючи конструкцію foreach. Однак при спробі відкомпілювати таку програму виникне помилка компіляції, яка скаже, що не реалізований метод GetEnumerator інтерфейсу IEnumerable, який знаходиться в просторі імен System.Collections. Для її вирішення доведеться класи отнаследовать від інтерфейсу IEnumerable (використовується для проходу по колекції) і створити тіло для необхідного методу.

Після цього foreach вже компілюватиметься, але для того щоб прохід по об'єктах класів відбувся потрібно реалізувати методи інтерфейсу IEnumerator, які неявно будуть викликатися при виконанні foreach.В інтерфейсі IEnumerator всього 2 методу і 1 властивість.

Методи

bool MoveNext (); // перехід на наступний елемент колекції

void Reset (); // перехід на початок колекції.

Під колекцією мається на увазі набір елементів якого - типу

Властивість

object Current {get;} // повертає значення поточного елемента колекції

Наш клас - контейнер зобов'язаний реалізувати зазначені вище методи і властивості.

Використання ключового слова yield в C #

Якщо в методі або властивості зустрічається yield, то даний метод або властивість є ітератором. yield слід застосовувати, коли необхідно отримати можливість ітерованих деякі елементи класу. Це можна робити задіявши інтерфейс IEnumerable або створивши свій метод або властивість, що використовує yield.

В одиночному лямбда-виразі частина, яка перебуває праворуч від оператора =>, впливає на параметр (або ряд параметрів), що вказується зліва. Повертаним результатом обчислення такого виразу є результат виконання лямбда-оператора. Нижче наведена загальна форма одиночного лямбда-вирази, що приймає єдиний параметр:

параметр => вираз

Якщо ж потрібно вказати кілька параметрів, то використовується наступна форма:

(спісок_параметров) => вираз

Таким чином, коли потрібно вказати два параметра або більше, їх слід укласти в дужки. Якщо ж вираз не вимагає параметрів, то слід використовувати порожні дужки.

Лямбда-вираз застосовується в два етапи. Спочатку оголошується тип делегата, сумісний з лямбда-виразом, а потім екземпляр делегата, якому присвоюється лямбда-вираз. Після цього лямбда-вираз обчислюється при зверненні до примірника делегата. Результатом його обчислення стає повертається значення (В підручнику см.тема 3-делегати, події, лямбда. Конкрктном про анонімні методах і лямбда-виразах в 3.16).

Розглянемо приклад:

using System;

namespace ConsoleApplication1
{
   // Створимо кілька делегатів імітують
     // найпростішу форму реєстрації
    delegate int LengthLogin(string s);
    delegate bool BoolPassword(string s1, string s2);

    class Program
    {
        private static void SetLogin()
        {
            Console.Write("Введите логин: ");
            string login = Console.ReadLine();

            // Використовуємо лямбда-вираз
            LengthLogin lengthLoginDelegate = s => s.Length;

            int lengthLogin = lengthLoginDelegate(login);
            if (lengthLogin > 25)
            {
                Console.WriteLine("Слишком длинное имя\n");

                // Рекурсія на цей же метод, щоб ввести нові логін
                SetLogin();
            }
        }

        static void Main()
        {
            SetLogin();

            Console.Write("Введите пароль: ");
            string password1 = Console.ReadLine();
            Console.Write("Повторите пароль: ");
            string password2 = Console.ReadLine();

            // Використовуємо лямбда-вираз
            BoolPassword bp = (s1, s2) => s1 == s2;

            if (bp(password1, password2))
                Console.WriteLine("Регистрация удалась!");
            else
                Console.WriteLine("Регистрация провалилась. Пароли не совпадают");

            Console.ReadLine();
        }
    }
}


Продовжимо наш проект:

Результат.  

Вам пропонується створити Windows Forms додаток, розмістити на формі свою фотографію, варіант, прізвище та результати роботи всіх трьох завдань.  

Один з варіантів користувальницького інтерфейсу:  

ЗАВДАННЯ

  1. ЗАВДАННЯ (Створити WF - додаток)
  2. ПИТАННЯ

Назад Уперед Зміст