maran program engineering (830029), страница 20
Текст из файла (страница 20)
Подтверждение изменения фамилии на"+s2 ,"Изменение фамилии" , MessageBoxButtons.YesNo))Form1.qa.Updte(s1, s2);textBox4.Clear();textBox5.Clear();f1.studentsTableAdapter.Fill(f1.data0512DataSet.Students);// Обновим представление таблицы в нашем приложении}catch{MessageBox.Show("Такого студента нет");}}}Создание и открытие этой формы традиционно, и мы его не приводим.1125.5.7.
Использование данных из базы для вычисленийВ принципе существуют два подхода к использованию данных из базыдля вычислений в своей программе.1. Существует стандартный класс DataTable, которым мы уже неоднократнопользовались. Можно записать нужные данные в него (таблицу базы данных, представление или результат функции) и выполнять обработку. Внесенные при обработке изменения в базу данных не передаются.2.
Можно работать непосредственно с таблицами базы данных. Тогда можно передать туда и изменения. Можно работать и с представлениями, нотогда изменения невозможны.Кроме того, покажем на этом примере прямой доступ к данных по ключу:так как ключ не может повторяться, то либо будет найдена единственнаязапись, или ничего.Форма для обоих случаев представлена на рис. 5.13.Рис. 5.13Модуль этой формы:publicForm1 f1;public DataTable tabl1;public Form7(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){// Работаем с DataTable.// вычисляем средний рост студентов, ростом выше с.Double temp, sum = 0;int kol = 0;double c = Double.Parse(textBox1.Text);113for(int i=0; i<tabl1.Rows.Count; i++){temp = Convert.ToDouble(tabl1.Rows[i][“Rost”]);/* Обращение к столбцам возможно как по имени,так и по номеру.Преобразование типа данных всегда обязательно!*/if(temp>c){sum += temp;kol++;}}if (kol != 0){sum = sum / kol;label1.Text = sum.ToString(“F2”);}elselabel1.Text = «Таких нет»;// Решение этой же задачи с помощью языка LINQkol = f1.data0512DataSet.Students.Where(p =>p.Rost > c).Count();if (kol != 0){//Функция Average() выдает ошибку при отсутствии данныхlabel1.Text = (f1.data0512DataSet.Students.Where(p => p.Rost >c).Select(q =>Convert.ToDouble(q.Rost)).Average()).ToString(“F2”);// Преобразование типа данных всегда обязательно!}elselabel1.Text = “Таких нет”;}private void button2_Click(object sender, EventArgs e){// работа непосредственно с таблицей базы данных,// внесение измененийint temp;for(int i=0;i<f1.data0512DataSet.Students.Rows.Count;i++){temp = Convert.ToInt32(f1.data0512DataSet.Students.Rows[i][“Ves”]);temp -= 5;f1.data0512DataSet.Students.Rows[i][“Ves”]=temp;114}f1.studentsTableAdapter.Update(f1.data0512DataSet.Students);}private void button3_Click(object sender, EventArgs e){ //Поиск данных по ключу.DataRow стандартный класс// для представления строки таблицыDataRow dr;try{ // Если искомого ключа нет, то возникает исключение.dr = f1.data0512DataSet.Students.FindByTabNum(textBox2.Text);label6.Text = dr[1].ToString();// вывод фамилии найденного студента}catch{label6.Text = «Нет в списке»;}} }Открытие этой формы:private void получениеРезультатаToolStripMenuItem_Click(object sender,EventArgs e){Form7 f77;f77 = new Form7();f77.f1 = this;f77.tabl1 = studentsTableAdapter.GetData();f77.Show();}5.6.
Использование стандартных классовв реализацииНа языке С# имеется набор классов для работы с динамическими структурами данных. Использование этих классов в практическом программировании желательно, особенно при работе с большими объемами данных: с однойстороны, таким образом можно повысить производительность труда программистов и, с другой стороны, повысить и эффективность создаваемых программ.115Ограничимся в данном пособии рассмотрением стандартных классов список —List и словарь — Dictionary.5.6.1. Работа с классом ListДля начала проведем краткое сравнение двух способов агрегации данных:массивов и списков.
Преимуществами массивов является быстрота адресации,потому что элементы расположены в памяти друг за другом и всегда имеютодинаковую структуру и одинаковый объем занимаемой памяти. Но при необходимости частого удаления и добавления элементов, особенно если требуетсяих упорядоченность, возникают существенные трудности. Элементы списковсвязаны друг с другом с помощью адресов связи, поэтому их удаление и добавление не требуют перемещения остальных элементов.
Отсюда рекомендация:списки предпочтительны при высокой динамичности их состава. Рассмотримработу с классом List в двух случаях:• Список состоит из стандартных данных С#.• Список состоит из данных, структура которых определена пользователем.Список из стандартных данныхПриведем пример, в котором показаны все основные действия над классом List. Рассмотрим подробно функциюstatic int c;static bool pred(intx){ // условие поиска и/или удаления элементовreturn(x>c);}Как видно из комментария, она предназначена для определения условий,которые потом будут использованы при поиске и удалении элементов списка.Атрибут static выбирается по обычным правилам.
Интерфейс функции строгофиксирован:bool имя_функции (параметр_типа _элемент_списка){......}Глобальная переменная с необходима для внесения в функцию параметра,так как состав формальных параметров фиксирован, то другого пути нет. Разумеется, количество таких функции не ограничено.namespace ListInt{class Program{static int c;static bool pred(int x){// условие поиска и/или удаления элементовif (x > c) return true;else return false;}116static void Main(string[] args){List<int> lst1, lst2;int el,kol;bool b1;lst1 = newList<int>();// Для создания списка запускаем конструктор класса Listfor (int i = 0; i < 6; i++){// Заполнение спискаConsole.Write("Введите элемент " + i+" ");el = Convert.ToInt32(Console.ReadLine());lst1.Add(el); // добавление элемента в список}// Допустим, что введены элементы 3, 12, -4, 65, 9, 100// Начинаем обработку спискаb1 = lst1.Contains(65);// Содержится ли в списке заданный элемент, ответ truec = 25;kol = lst1.Find(pred);/* Будет найден 1-й элемент, удовлетворяющий условию,в данном случае 1-й элемент больше 25, при егоотсутствии ответ 0, в нашем случае ответ 65*/kol = lst1.FindLast(pred);/* Будет найден последний элемент, удовлетворяющийусловию, в данном случае последний элемент больше 25,приего отсутствии ответ 0, в нашем случае ответ 100 */kol = lst1.FindIndex(pred);/* Будет найден индекс первого элемента,удовлетворяющего условию, в нашем случае ответ 3,при отсутствии искомого элемента ответ -1аналогично FindLastIndex()*/kol = lst1.IndexOf(9);/* Будет найден индекс первого вхождения заданногоэлемента, в нашем случае ответ 4при отсутствии искомого элемента ответ -1*/lst2 = lst1.FindAll(pred);/* Все элементы lst1, удовлетворяющие условию,будут размещены в lst2.
Так как их количество заранеенеизвестно,то для приема ответа нужен список или массив*/int[] res = lst1.FindAll(pred).ToArray();// запись результата в массив, ответ 65 100117lst2 = res.ToList();// существует и функция переноса массива в списокlst1.Sort();// Сортировка списка по возрастаниюlst1.Reverse();// Изменение очередности элементов на противоположноеel = 125;lst1.Insert(3, el);/* Добавление нового элемента в заданное место.В нашем случае 125 займет 4-е с начала списка место.Размещение нового элемента за пределамисписка - ошибка!Расширение списка - см. выше!*/lst1.Remove(-4);/* Удаление заданного элемента из списка,при его отсутствии ничего не делается,но это и не ошибка!*/lst1.RemoveAt(0);// Удаление элемента по индексу.//Попытка удаления элемента за пределами списка - ошибка!lst1.RemoveAll(pred);// Удаление всех элементов, удовлетворяющих условию.// Обработка элементов спискаfor (int i = 0; i < lst1.Count; i++)lst1[i] = 48 * lst1.ElementAt(i);/* Для изменения значения элемента - только lst1[i]Для извлечения значения элемента - оба вариантаlst1.Count - количество элементов в списке */Console.WriteLine("*********************************");// Второй вариант извлечения элементов списка.// Не забудьте про ограничения на foreach!foreach (int x in lst1)Console.WriteLine("" + x);Console.ReadLine();}}}Список со своими элементамиДля создания и обработки списка со своими элементами следует сначалаопределить структуру элементов и функции для их обслуживания (минимальный набор — ввод и вывод).
Структуру элементов списка можно задать спомощью двух конструкций языка C#: struct и class. Напомним, что классы118являются ссылочными данными, поэтому список из переменных типа класс —это по существу список указателей на элементы. Структуры не являются ссылочными переменными, и соответствующий список состоит из самих экземпляров структур.Для задания условий на элементах списка используется описанная вышефункция. Если требуется выполнить упорядочивание элементов — то условиясортировки придется определить самому. Как это делать — рассмотрим позже.Использование struct.namespace ListStruct{struct elem{ // Задаем структуру элементов спискаpublic string s;public int k;public void inpt(){Console.Write("String "); s = Console.ReadLine();Console.Write("Number ");k = Int32.Parse(Console.ReadLine());}public void otpt(){Console.WriteLine(s + "" + k);}}class Program{static int upor(elem x1, elem x2){ // функция задает условие упорядочения по sreturn x1.s.CompareTo(x2.s);}static int c;static bool udal(elem x){ // функция задает условие на элементахreturn(x.k>= c);}static void Main(string[] args){List<elem> lst1, lst2;lst1 = new List<elem>();elem el;119///*/*/*int kol;string st1;Создание спискаel = new elem();for (int i = 0; i < 6; i++){el.inpt();lst1.Add(el);}el.s = "aaa";el.k = 25;kol = lst1.IndexOf(el);Работает ТОЛЬКО при использовании для элементов спискаstruct индекс будет найден при совпаденииВСЕХ компонентов элемента*/bool b1 = lst1.Contains(el);Работает ТОЛЬКО при использовании для элементов спискаstruct ответ будет true при совпаденииВСЕХ компонентов элемента*/lst1.Remove(el);Работает ТОЛЬКО при использовании для элементов спискаstruct удаление будет выполненопри совпадении ВСЕХ компонентов элементаОбработка элементов*/for (int i = 0; i < lst1.Count; i++){el = lst1[i];el.k = el.k + 100;lst1[i]=el;}lst1.Sort(upor);// сортировка элементов списка по критерию,//заданному в upor// Обработка элементов спискаforeach (elem x in lst1)x.otpt();c = 15;el = lst1.Find(udal);el.otpt();/* Будет найден и выведен первый элемент, удовлетворяющийусловию или 0120Powered by TCPDF (www.tcpdf.org)Аналогично работают и FindAll, FindLast и другие,рассмотренные в предыдущем примере*/Console.ReadLine();}}}Рассмотрим в следующем примере использование класса для задания структуры элементов списка.