Содержание
- 2. Понятие делегата Делегат – это вид класса, объекты которого могут ссылаться на методы. Делегат может вызвать
- 3. Делегаты предоставляют следующие возможности: динамическое определение вызываемого метода (не при компиляции, а во время выполнения программы);
- 4. Описание делегата [спецификатор ] delegate имя_делегата([параметры]); Описание делегата задает сигнатуру методов, которые могут быть вызваны с
- 5. Делегат может вызывать либо метод экземпляра класса, связанный с объектом, либо статический метод, связанный с классом.
- 6. Например, если в классе описан делегат public delegate double func( double x, y) ; а my_func
- 7. Например, F(3.5,2); Рассмотрим пример, демонстрирующий возможность динамически определять какой из методов в тот или иной момент
- 8. А также получить таблицу значений функции sin(t) для t принимающего значения от x до y. namespace
- 9. class Program { public static double tab(double xn, double xk) { double y=0; for (double x
- 10. static void Main(string[] args) { Console.WriteLine("Введите x и y"); double x = Convert.ToDouble(Console.ReadLine()); double y =
- 11. if(n = = 1) F= new func(function.f1); else if ( n= = 2) F = new
- 12. Если методы f1 и f2 будут нестатическими, то в программе понадобятся следующие изменения: function FF =
- 13. Если делегат хранит ссылки на несколько методов, то при вызове делегата эти методы вызываются последовательно в
- 14. Если параметр методов списка описан с ключевым словом out или методы возвращают значение, результатом выполнения делегата
- 15. public delegate void func(double x, double y); class function { public void f1(double x, double y)
- 16. class Program { public static void tab(double xn, double xk) { double y; for (double x
- 17. static void Main(string[ ] args) { Console.WriteLine("Введите x и y"); double x = Convert.ToDouble(Console.ReadLine( )); double
- 18. В результате выполнения этого фрагмента программы будут получены следующие результаты: x =1 y=2 sin(x)+cos(y)=0,425324148260754 x =1
- 19. После выполнения следующих операторов F - = function.f2; F(x, y); x =1 y=2 sin(x)+cos(y)=0,425324148260754 1 0,841470984807897
- 20. Следующий пример показывает передачу значений при многоадресной передаче. public delegate void str(ref string s); class Stroki
- 21. Тогда выполнение следующих операторов string stroka = "Ча-ча-ча"; str S = null; S += Stroki.rs; S
- 22. Передача делегатов в методы Так как делегат – это класс, его экземпляры можно передавать в методы
- 23. public static void Tab(double xn, double xk, double dx, Func F) { Console.WriteLine("╔═════════════╦════════════════╗"); Console.WriteLine("║ Аргумент ║
- 24. public static double f1(double x) { return Math.Cos(x) + Math.Sin(x); } public static double f2(double x)
- 25. Console.WriteLine("cos(x)-sin(2x)"); Tab(-2, 2, 0.2, new Func(f2)); Console.WriteLine("cos(x)"); Tab(0, 2, 0.1, new Func(Math.Cos)); Console.ReadKey( ); } }
- 26. Tab( -3, 3, 0.5, f1); Tab(-2, 2, 0.2, f2); Tab(0, 2, 0.1, Math.Cos); Например, наряду с
- 27. Например, class dd { public static void z(Program.Func F, double x) { Console.WriteLine(F(x)); } } Тогда
- 28. Анонимный метод – это фрагмент кода, описываемый в месте использования делегата следующим образом: delegate( ) {
- 29. Обеспечение связи «источник - наблюдатель» между объектами При использовании множества совместно работающих классов появляется необходимость поддерживать
- 30. Для обеспечения такой связи между объектами применяется следующая схема (шаблон проектирования, паттерн), получившая название паттерн «наблюдатель».
- 31. Для этого можно использовать делегат с многоадресатной передачей: при регистрации будет формироваться список вызовов из методов
- 32. public void Registracija(Nab N) { Nab_li += N; } public void K_D(double kd) { kurs_dol =
- 33. class Student { string Fam; double stip, stip_dol; public Student(string fm, double st) { Fam =
- 34. public void S_D(object ob) { stip_dol = stip/((Bank)ob).KD; } } // реакция на изменение в //
- 35. Student S1 = new Student("Тяпкин", 150000); Student S2 = new Student("Ляпкин", 150000); Student S3 = new
- 36. Я – Тяпкин, моя стипендия: 60$ Я – Ляпкин, моя стипендия: 60$ Я – Пупкин, моя
- 37. Операции с делегатами. Для делегатов можно использовать операции равно == и не равно !=. Делегаты равны,
- 38. Func F1 = Math.Sin; F1 += Math.Cos; Func F2 = Math.Cos; F2 += Math.Sin; Console.WriteLine("F1 =
- 39. получим F4 = F4 : True Для однотипных делегатов можно выполнять операции присваивания, += и -=
- 40. делегат F будет содержать ссылки на методы Math.Sin и Math.Cos. Результатом операции += будет делегат, список
- 41. public static void V1(double x) { Console.WriteLine("cos="+Math.Cos(x)); } public static void V2(double x) { Console.WriteLine("sin="+Math.Sin(x)); }
- 42. Тогда после выполнения операторов Func1 FF1 = V1; FF1 += V2; Func1 FF2 = V3; FF2
- 43. Результатом операции -= будет делегат, список вызовов которого содержит список вызовов делегата в левой части оператора
- 44. Func1 FF3 = delegate(double x) { Console.WriteLine("x=" + x); }; FF2 -= FF3; FF2(3); Результат: 2x
- 45. С делегатами одного и того же типа можно выполнять операции сложения и вычитания: FF3 = FF2
- 46. Например, baza1.txt: Плановый отдел;48-35-80;10 Отдел кадров;48-15-35;15 Бухгалтерия;48-05-55;5 baza2.txt: Плюшкин И.И.;Бухгалтерия;15;200 Коклюшкин В.В.;Плановый отдел;20;300 Финтифлюшкин С.А.;Бухгалтерия;12;150 Замухрышкин
- 47. Разработать программу, которая выполняет следующие действия: - Считывает информацию из первого файла в массив объектов класса
- 48. Класс Сотрудник должен содержать следующие элементы: поля для хранения фамилии, названия отдела, рабочего телефона, зарплаты, премии
- 49. - Реализует шаблон «наблюдатель», в котором при изменении размера премии в процентах для сотрудников, стаж которых
- 50. string name, telefone; int premija; Nab Nab_li_prm, Nab_li_tlfn; public Otdel(string nm, string tlfn, int prm) {
- 51. public void Prem(int procent) { premija = procent; if (Nab_li_prm != null) Nab_li_prm(this); } public void
- 52. public string Name { get { return name; } } public int Premija { get {
- 53. class Sotrudnic : IComparable { string fam, naz_otdel, rab_tel; int staz; double zarplata, premia; public Sotrudnic(string
- 54. public void PR(object ob) { premia = ((Otdel)ob).Premija * zarplata / 100; } public void R_T(object
- 55. public int CompareTo(object obj) { Sotrudnic std = obj as Sotrudnic; return naz_otdel.CompareTo(std.naz_otdel); } } class
- 56. StreamReader f1 = new StreamReader("baza1.txt"); string s = f1.ReadLine(); int j = 0; while (s !=
- 57. Otdel[ ] ot = new Otdel[j]; f1 = new StreamReader("baza1.txt"); s = f1.ReadLine( ); j =
- 58. f1.Close(); foreach (Otdel otd in ot) otd.vivod( ); StreamReader f2 = new StreamReader("baza2.txt"); s = f2.ReadLine();
- 59. Sotrudnic[ ] st = new Sotrudnic[j]; f2 = new StreamReader("baza2.txt"); s = f2.ReadLine(); j = 0;
- 60. while (i { if (st[j].Naz_o = = ot[i].Name) { ot[i].Registracija_tlfn(st[j].R_T); if (st[j].Staz > 12) ot[i].Registracija_prm(st[j].PR); i
- 61. s = f2.ReadLine(); j++; } f2.Close(); foreach (Otdel otd in ot) { otd.Tel(otd.Telefone); otd.Prem(otd.Premija); } Array.Sort(st);
- 62. for (int i = 1; i { if (st[i].Naz_o != st[i - 1].Naz_o) Console.WriteLine(st[i].Naz_o); st[i].vivod(); }
- 63. foreach (Otdel otd in ot) {if (otd.Name == s_o) otd.Tel(t_o); } Console.Clear(); Console.WriteLine(st[0].Naz_o); st[0].vivod(); for (int
- 64. Console.WriteLine("Премия увеличивается на 5%"); foreach (Otdel otd in ot) { otd.Prem(otd.Premija+5); } foreach (Sotrudnic std in
- 65. События Событие – это элемент класса, позволяющий автоматически уведомлять объекты других классов об изменении своего состояния.
- 66. Когда ожидаемое событие происходит (посылается уведомление), вызываются все зарегистрированные обработчики. Методы-обработчики событий вызываются с помощью делегатов.
- 67. Чтобы использовать в классе событие, нужно Описать делегат, задающий сигнатуру обработчиков события. Описать в классе событие
- 68. ( ); Поскольку события обычно предназначены для многоадресатной передачи, они должны возвращать значение типа void. Для
- 69. Например: public delegate void Nab(object ob); class Bank { public string name; double kurs_dol; public event
- 70. public double KD { get { return kurs_dol; } } } class Student { string Fam;
- 71. public void S_D(object ob) { stip_dol = stip/((Bank)ob).KD; } public void vivod( ) { Console.WriteLine("Я -
- 72. Bank B = new Bank(); B.name = "Беларусбанк"; Student S1 = new Student("Тяпкин", 150000); Student S2
- 73. Существует еще одна форма описания события: [спецификаторы] event { add {Код добавления события в цепочку событий}
- 74. Средство доступа remove вызывается, когда с помощью операции "-=" из цепочки событий удаляется новый обработчик. Средство
- 75. public delegate void s_n(); class key { static s_n[ ] sn = new s_n[3]; public static
- 76. remove { for (int i = 0; i { if (sn[i] == value) { sn[i] =
- 77. public static void OnPressKey(ConsoleKey k) { for (int i = 0; i { if (("On" +k.ToString())
- 78. class Program { static void OnDelete( ) { Console.WriteLine("Delete!"); } static void OnInsert( ) { Console.WriteLine("Insert!");
- 79. static void Main(string[ ] args) { key.naz_klav += OnDelete; key.naz_klav += OnInsert; key.naz_klav += OnHome; key.OnPressKey(Console.ReadKey(true).Key);
- 80. key.OnPressKey (Console.ReadKey(true).Key); Console.ReadKey(); } } Результат после нажатия Delete: Delete! Delete в ff
- 81. Правила обработки событий в среде .Net и использование встроенного делегата EventHandler. Для создания .NET-совместимых событий рекомендуется
- 82. - второй параметр должен иметь тип EventArgs или производный от него, этот параметр задает остальную необходимую
- 83. Например, в пример о студентах, наблюдающих за изменениями курса доллара, можно внести такие изменения: Событийный делегат
- 84. Метод-обработчик события из класса Student – public void OnS_D(object ob,EventArgs arg) { stip_dol = stip/((Bank)ob).KD; }
- 85. Для иллюстрации передачи в методы-обработчики дополнительной информации переработаем пример с обработкой события нажатия клавиши. Предусмотрим передачу
- 86. public static event s_nEventHandler naz_klav { add { for (int i = 0; i { if
- 87. remove { for (int i = 0; i { if (sn[i] == value) { sn[i] =
- 88. public void OnPressKey(ConsoleKey k) { KeyEventArgs kk=new KeyEventArgs(); kk.klav = k; for (int i = 0;
- 89. static void OnDelete(object ob, KeyEventArgs args) { Console.WriteLine(args.klav + " удаление"); } static void OnInsert(object ob,
- 90. Например, в примере о студентах-наблюдателях при использовании этого типа делегата становится ненужным объявление событийного делегата, а
- 91. - предоставляет возможность пользователю выполнять следующие действия по нажатию определенной клавиши: PageUp – зарплата у всех
- 92. public delegate void s_n(); class key { static int n; static s_n[ ] sn; public static
- 93. add { for (int i = 0; i { if (sn[i] == null) { sn[i] =
- 94. public static void OnPressKey(ConsoleKey k) { for (int i = 0; i { if (sn[i]!=null &&
- 95. class Sotrudnic { string fam, naz_otdel; int staz; double zarplata; public Sotrudnic(string fm, string nazotd, int
- 96. public void vivod( ) { Console.WriteLine(fam + " " + naz_otdel + " " + staz
- 97. class Program { static bool p; static void OnDelete() { Console.WriteLine("Увольнение молодых и неопытных!"); } static
- 98. static void Main(string[ ] args) { StreamReader f2 = new StreamReader("baza2.txt"); string s = f2.ReadLine(); int
- 99. Sotrudnic[ ] st = new Sotrudnic[j]; key.N = 2 * j+2; f2 = new StreamReader("baza2.txt"); s
- 100. key.naz_klav += st[j].OnPageDown; key.naz_klav += st[j].OnPageUp; s = f2.ReadLine(); j++; } f2.Close(); foreach (Sotrudnic sss in
- 102. Скачать презентацию