Тип элементов массивов зависит от варианта работы. Массивы должны иметь одинаковое число элементов. Если число строк в двумерном прямоугольном массиве равно 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 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, который имеет
/// Класс обеспечивает объектное представление свойств студента, а также простой доступ к ним. 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 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 приложение, разместить на форме свою фотографию, вариант, фамилию и результаты работы всех трех задач.
Один из вариантов пользовательского интерфейса: