Тип елементів масивів залежить від варіанту роботи. Масиви повинні мати однакове число елементів. Якщо число рядків в двовимірному прямокутному масиві одно nrow, а число стовпців ncolumn, то одновимірний масив повинен містити nrow * ncolumn елементів, в двовимірному ступеневу масиві загальне число елементів також має дорівнювати nrow * ncolumn.
Значення nrow і ncolumn вводяться в процесі роботи програми у вигляді одного рядка з роздільниками. У запрошенні, яке отримує користувач, повинна бути інформація про те, які символи можна використовувати як роздільники, число роздільників повинно бути більше 1. За допомогою методу Split класу System.String додаток розбирає введену користувачем текстовий рядок з інформацією про кількість рядків і числі стовпців двовимірного масиву і привласнює значення змінним, які містять значення nrow і ncolumn. У першій лабораторній роботі не потрібно обробляти помилки введення, передбачається, що користувач правильно ввів дані. Додаток розподіляє пам'ять для всіх масивів і ініціалізує елементи масивів. Для ініціалізації елементів можна використовувати конструктор без параметрів.
Для всіх елементів масивів виконується одна і та ж операція, наприклад, присвоюється значення одному з властивостей, певних для елементів масиву. У лабораторній роботі потрібно порівняти час виконання цієї операції для одновимірного, двовимірного прямокутного і двовимірного ступеневої масивів з однаковим числом елементів.
Для вимірювання часу виконання операцій можна використовувати властивість Environment.TickCount. Cтатіческое властивість TickCount класу Environment має тип int, використовує інформацію системного таймера і містить час в мілісекундах, який минув з моменту перезавантаження комп'ютера. Щоб отримати час виконання деякого блоку коду, необхідно викликати Environment.TickCount безпосередньо перед блоком і відразу ж після останнього оператора блоку і взяти різницю значень.
В блоці коду, для якого вимірюється час, не повинно бути операцій розподілу пам'яті для масивів, ініціалізації елементів масивів і операцій виведення даних на консоль. Блоки коду повинні містити тільки операції з елементами масиву. Попередньо обчислені значення часу виконання операцій для трьох типів масивів, а також число рядків nrow і стовпців ncolumn виводяться на консоль. Висновок повинен бути підписаний, тобто висновок повинен містити інформацію про те, якого типу масиву відповідає виведене значення. ?
Створюємо проект 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 ListTests; 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 ()
Клас Test, що задає уявлення заліку в цій програмі
/// Клас, що задає уявлення заліку в цій програмі /// Клас, що задає об'єктне уявлення іспиту в даній програмі class Exam { public string SubjectName; public int Mark {get; set; } public DateTime Date {get; set; } ////// Конструктор з параметрами класу Exam /// summary> public Exam (string SubjectName, int Mark, DateTime DateOfExam) { this.SubjectName = SubjectName; this.Mark = Mark; Date = DateOfExam; } /// /// Конструктор без параметрів класу Exam /// summary> 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, який має
/// Клас забезпечує об'єктне уявлення властивостей студента, а також простий доступ до них. 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()); }
Результат.
Перевизначення віртуального методу int GetHashCode () також має бути узгоджено з операціями == і! =. Віртуальний метод GetHashCode () використовується деякими класами базової бібліотеки, наприклад, колекціями-словниками. Класи базової бібліотеки, що викликають метод GetHashCode () з призначеного для користувача типу, припускають, що рівним об'єктів відповідають рівні значення хеш-кодів. Тому в разі, коли під рівністю об'єктів розуміється збіг даних (а не посилань), реалізація методу GetHashCode () повинна для об'єктів з однаковими даними повертати рівні значення хеш-кодів.
В задаче3 потрібно визначити клас, що містить типізовану колекцію, який за допомогою подій сповіщає про зміни в колекції.
Колекція складається з об'єктів посилальних типів. Колекція змінюється при видаленні / додаванні елементів або при зміні однієї з вхідних в колекцію посилань, наприклад, коли однією з посилань присвоюється нове значення. В цьому випадку у відповідних методах або властивості класу кидаються події.
При зміні даних об'єктів, посилання на які входять в колекцію, значення самих посилань не змінюються. Цей тип змін не породжує подій.
Для подій, що сповіщають про зміни в колекції, визначається свій делегат. Події реєструються в спеціальних класах-слухачах.
Вимоги до програми
void StudentListHandler (object source, StudentListHandlerEventArgs args);
Клас Journal зберігає інформацію в списку об'єктів типу JournalEntry.
Створюється інтерфейс для класів, які містять дату і метод повного копіювання, причому всі дочірні об'єкти нового класу не були б посиланнями на дочірні об'єкти копійованого класу.
В темі 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, то даний метод або властивість є ітератором. 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 додаток, розмістити на формі свою фотографію, варіант, прізвище та результати роботи всіх трьох завдань.
Один з варіантів користувальницького інтерфейсу: