Перегрузка конструкторов, функций, операторов и операций 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Перегрузка конструкторов, функций, операторов и операций



Факультет информационных технологий и прикладной математики

Кафедра вычислительной математики и программирования

 

Лабораторные работы 1 — 9 по курсу ООП:
основы программирования на С#

 

0.Перегрузка

1.Агрегация по ссылке

2.Агрегация по значению и вложением

3.Принцип подстановки

4.Наследование: расширение, спецификация, специализация, конструирование и комбинирование

5.Наследование: комбинирование через общих предков

6.Ассоциация(один к одному, один ко многим)

7.Использование

8.Конкретизация

9. АНОНИМНЫЕ ФУНКЦИИ: delegate, ЛЯМБДА ВЫРАЖЕНИЕ. Event

 

Работу выполнила:

8О-203Б........................    _________ Вариант 15

 

Руководитель: _______/Семенов А.С.


Дата: ___ октября 2019

Перегрузка конструкторов, функций, операторов и операций

 

Текст программы:

using System;

using System.Collections.Generic;

using System.Linq;

 

using System.Text;

using System.Threading.Tasks;

 

namespace lab0

{

 

class P

{

   int f = 0;

       

   public P() { Console.WriteLine("This is constructor."); }

   public P(int f) { Console.WriteLine("This is new constructor"); this.f = f; }

   public void print()

   {

       Console.WriteLine("Oh, it is wonderful day =)");

   }

   public void print(string In)

   {

       Console.WriteLine($"Hello, {In} ");

   }

 

}

 

class Reestr

{

   string sur;

   int n;

   int year;

   int time;

   public Reestr(string sur = "Aladin", int n = 5, int year = 2000, int time = 10)

   {

       //Console.WriteLine("Reestr");

       this.sur = sur;

       this.n = n;

       this.year = year;

       this.time = time;

   }

   public void print_r()

   {

       Console.Write($"{sur}\t");

       Console.Write($"{n}\t");

       Console.Write($"{year}\t");

       Console.WriteLine($"{time}");

       Console.WriteLine("________________________________");

   }

   public static Reestr operator +(Reestr r1, Reestr r2)

   {

       return new Reestr { n = r1.n + r2.n + 200 };

   }

   public int N //атрибут доступа

   {

       get { Console.WriteLine(" "); return this.n; }

       set

       {

           if (value > 12) throw new ArgumentOutOfRangeException();

           Console.WriteLine("{0}", this.n = value);

       }

   }

 

   class MainClass

   {

       public static void Main(string[] args)

       {

           Console.WriteLine("What is your name?");

           string st = Console.ReadLine();

           P p = new P();

           p.print();

           p.print(st);

           P p = new P(f);

           Console.WriteLine('\n');

           Console.WriteLine("\t +++Reestr+++");

           Console.WriteLine("________________________________");

           Reestr r0 = new Reestr("A", 9);

           r0.print_r();

           Reestr r1 = new Reestr("Homskiy", 1, 1950, 33);

           r1.print_r();

           Reestr r2 = new Reestr("Lindman", 2, 1950, 55);

           r2.print_r();

           Reestr r3 = new Reestr("Ulman", 3, 1961, 60);

           r3.print_r();

           Reestr r = new Reestr();

           r = r1 + r2;

           r.print_r();

           try

           {

               r.N = System.Convert.ToInt32(Console.ReadLine());

           }

           catch

           {

               Console.WriteLine("Format exepction");

           }

 

           r.print_r();

       }

   }

}

}

Результат работы:

Вывод: перегрузка конструкторов, функций, операторов и операций позволяет определить структурный полиморфизм, когда с данным именем существуют несколько функций с разным поведением, а также с различным списком аргументов, который определит, какая функция будет вызываться.


 

Текст программы

using System;

using System.Collections.Generic;

using System.Linq;

 

using System.Text;

using System.Threading.Tasks;

 

namespace lab1_AgregationLink

{

class Program

{

   class A

   {

       public A(B b, C c)

       {

           this.b = b;

           this.c = c;

 

           c.cq = 24;

       }

       ~A() { }

 

       public void mA()

       {

           Console.WriteLine("method of A");

       }

 

       public B bA

       {

           set { Console.WriteLine("set b"); b = value; }

           get { Console.Write("get b ->"); return b; }

       }

       public C cA //возвращает ссылку на обьект С, у которого вызывается метод сА - атрибут доступа

       {

           set { Console.WriteLine("set c"); c = value; }

           get { Console.Write("get c ->"); return c; }

       }

 

       private B b = null;

       private C c = null;

   }

 

   class B

   {

       public B(D d)

       {

           this.d = d;

       }

       ~B() { }

       public void mB()

       {

           Console.WriteLine("mthod of B");

       }

       public D dA

       {

           set { Console.WriteLine("set d"); d = value; }

           get { Console.Write("get d ->"); return d; }

       }

 

       private D d = null;

   }

 

   class C

   {

       public C(E e, J j)

       {

           this.e = e;

           this.j = j;

       }

       ~C() { }

 

       public void mC()

       {

           Console.WriteLine("method of C");

       }

 

       public E eA

       {

           set { Console.WriteLine("set e"); e = value; }

           get { Console.Write("get e ->"); return e; }

       }

 

       public J jA

       {

           set { Console.WriteLine("set j"); j = value; }

           get { Console.Write("get j ->"); return j; }

       }

 

       //атрибут доступа

       public int cq { get; set; }

 

       private E e = null;

       private J j = null;

   }

 

   class D

   {

       public D() { }

       ~D() { }

       public void mD()

       {

           Console.WriteLine("Method of D");

       }

   }

 

   class E

   {

       public E() { }

       ~E() { }

       public void mE()

       {

           Console.WriteLine("Method of E");

       }

   }

 

   class J

   {

       public J(K k)

       {

           this.k = k;

       }

       ~J() { }

       public void mJ()

       {

           Console.WriteLine("Method of J");

       }

       public K kA

       {

           set { Console.WriteLine("set k"); k = value; }

           get { Console.Write("get k ->"); return k; }

       }

       private K k = null;

   }

 

   class K

   {

       public K() { }

       ~K() { }

       public void mK()

       {

           Console.WriteLine("Method of K");

       }

   }

   static void Main(string[] args)

   {

       //создание объектов, которые будут частью других объектов

       D d = new D();

       E e = new E();

       K k = new K();

 

       //передаем выше созданные объекты классов в виде параметра в конструкторы классов B, C и A.

       B b = new B(d);

       J j = new J(k);

       C c = new C(e, j);

       A a = new A(b, c);

 

 

       //печать атрибута доступа

       Console.WriteLine("печать атрибута доступа:");

       Console.WriteLine(c.cq);

 

       //проверка, что передаётся по ссылке

       Console.WriteLine("передача по ссылке:");

       a.mA();

       a.bA.mB();

       a.cA.mC();

 

       a.bA.dA.mD();

 

       a.cA.eA.mE();

       a.cA.jA.mJ();

 

       a.cA.jA.kA.mK();

 

        Console.ReadKey();

   }

}

}       

Результат работы программы:

Вывод: Объекты всех классов существуют независимо друг от друга. Связывание объектов происходит с помощью конструктора.Например, b, c — параметры для конструктора класса A; d — для конструктора класса B; e, f — для конструктора класса C. Объекты могут быть уничтожены по отдельности. Это нарушит целостность структуры. Если удалить объект a, объекты b, c и т.д будут продолжать существовать и дальше. Агрегация по ссылке очень выгодна, так как она расходует очень мало памяти.

Агрегация по значению.

 
                 

рис.2. Диаграмма классов: агрегация по значению.

 


                                                                                         ось объектов

 

 

 


Текст программы:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace lab2_AgregationAtt

{

class Program

{

   class A

   {

       public A() { c.c1 = 40; }

       ~A() { }

 

       public void mA() { Console.WriteLine("method of A"); }

 

       public B bA { get { Console.Write("get b ->"); return b; } }

       public C cA { get { Console.Write("get c ->"); return c; } }

 

       private B b = new B();

       private C c = new C();

   }

 

   class B

   {

       public B() { }

       ~B() { }

       public void mB() { Console.WriteLine("method of B"); }

 

       public D dA { get { Console.Write("get d ->"); return d; } }

 

       private D d = new D();

 

   }

 

   class C

   {

       public C() { this.c1 = 15; }

       ~C() { }

 

       public void mC() { Console.WriteLine("method of C"); }

 

       public E eA { get { Console.Write("get e ->"); return e; } }

       public J jA { get { Console.Write("get j ->"); return j; } }

 

       private E e = new E();

       private J j = new J();

 

       public int c1 { get; set; }

   }

 

   class D

   {

       public D() { }

       ~D() { }

       public void mD() { Console.WriteLine("method of D"); }

   }

 

   class E

   {

       public E() { }

       ~E() { }

       public void mE() { Console.WriteLine("method of E"); }

   }

 

   class J

   {

       public J() { this.c1 = 20; }

   ~J() { }

       public void mJ() { Console.WriteLine("method of J"); }

 

       public K kA { get { Console.Write("get k ->"); return k; } }

       private K k = new K();

       public int c1 { get; set; }

   }

 

   class K

   {

       public K() { }

       ~K() { }

       public void mK() { Console.WriteLine("method of K"); }

   }

 

   static void Main(string[] args)

   {

       A a = new A();

       //вкладываем в a

       a.mA();

       a.bA.mB();

       a.cA.mC();

 

       //вкладываем в a -> b - >

       a.bA.dA.mD();

 

       //вкладываем в a -> c - > e & a -> c ->f

       a.cA.eA.mE();

       a.cA.jA.mJ();

 

       a.cA.jA.kA.mK();

 

       Console.ReadKey();

   }

}

}

Результат работы программы:

Вывод: при агрегации по значению все объекты класса существуют внутри объявленного класса. При таком виде агрегации невозможно удалить объекты, являющиеся частью объекта первого по иерархии класса. Например, b, c, j, k — части объекта а класса А(первый класс по иерархии); эти части создаются только при вызове конструктора класса A, а уничтожаются — при вызове деструктора А.

 

Агрегация вложением.

Текст программы:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace lab2_AgregationVal

{

       class Program

       {

   class A

   {

   public A() { c.c1 = 5; }

   ~A() { }

 

   public class B

   {

              public B() { }

              ~B() { }

 

              public class D

              {

              public D() { }

              ~D() { }

              public void mD() { Console.WriteLine(" method of D"); }

              }

 

              public void mB() { Console.WriteLine(" method of B"); }

              public D dA { get { Console.Write("get d -> "); return d; } }

 

              private D d = new D();

   }

 

   public class C

   {

              public C() { this.c1 = 10; }

              ~C() { }

              public class E

              {

              public E() { }

              ~E() { }

              public void mE() { Console.WriteLine(" method of E"); }

              }

 

              public class F

              {

              public F() { }

              ~F() { }

              public void mF() { Console.WriteLine(" method of F"); }

              }

 

              public void mC() { Console.WriteLine(" method of C"); }

              public E eA { get { Console.Write("get e ->"); return e; } }

              public F fA { get { Console.Write("get f ->"); return f; } }

 

              private E e = new E();

              private F f = new F();

 

              public int c1 { set; get; }

   }

 

   public class J

   {

              public J() { }

              ~J() { }

              public void mJ() { Console.WriteLine(" method of J"); }

   }

 

   public class K

   {

              public K() { }

              ~K() { }

              public void mK() { Console.WriteLine(" method of K"); }

   }

   public void mA() { Console.WriteLine(" method of A"); }

 

   public B bA { get { Console.Write("get b ->"); return b; } }

   public C cA { get { Console.Write("get c ->"); return c; } }

   public J jA { get { Console.Write("get j ->"); return j; } }

   public K kA { get { Console.Write("get k ->"); return k; } }

 

   private B b = new B();

   private C c = new C();

   private J j = new J();

   private K k = new K();

 

   }

   static void Main(string[] args)

   {

   //Создаем объект класса-родителя A

   A a = new A();

 

   //Проводим агрегацию по значению

   a.mA();

   //агрегируем в A: B, C, J, K

   a.bA.mB();

   a.cA.mC();

   a.jA.mJ();

   a.kA.mK();

 

   //агрегируем в B: D

   a.bA.dA.mD();

 

   //агрегируем в C: E, F

   a.cA.eA.mE();

   a.cA.fA.mF();

 

   Console.ReadKey();

   }

       }

}

Результат работы программы:

Вывод: при агрегации вложением определение классов происходит внутри классов, стоящих выше по иерархии. Все объекты создаваемого класса существуют внутри него самого. Как и в случае агрегации по значению уничтожение объектов, невозможно без уничтожения класса, стоящего выше по иерархии. Агрегация по ссылке намного лучше агрегации по значению или вложению, так как агрегация по ссылке расходует меньше памяти.

Комбинирование.

Текст программы:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace lab4_2

{

public interface C

{

   void mA();

   int fA();

}

 

public class B

{

   public B()

   {

       this.speed = 33;

   }

   ~B() { }

   public int speed { get; set; }

   //расширение по функции

   public virtual int K()

   {

       Console.WriteLine();

       return 1;

   }

}

//комбинирование

public class A: B, C

{

   public A() { this.size = 22; this.color = 1; }

   ~A() { }

   protected int size { set; get; }

   public int color { set; get; }

 

   public void mA() { this.color = this.color * this.size; }

   public int fA() { return this.color = 55; }

 

   public override int K() { return this.size = 22; }

       

}

class Program

{

   static void Main(string[] args)

   {

       C c = null;// пустая ссылка

       c = new A();

       Console.WriteLine("a.fA = {0}", c.fA());

       Console.WriteLine("method mA() of Interface A:");

       c.mA();

       Console.WriteLine("a.K() = {0}", ((B)c).K());// всё тоже самое как B c = new B() и вызов потом c.K() или по другому это преобразование типов

       Console.WriteLine();

       A d = new A();

       Console.WriteLine("d.K() = {0}", d.K());          

       Console.WriteLine("d.fA() = {0}", d.fA());

       Console.ReadKey();

   }

}

}


Результат работы программы:

Вывод: Комбинирование позволяет объединить черты нескольких классов и интерфейсов в одном дочернем классе.В моей программе реализовано наследование от двух интерфейсов А и В и класса С. Происходит множественное наследование, причем для каждого суперкласса можно определить свой вариант наследования, но если в наследуемых классах есть одинаковые методы и/или переменные неоднозначность использования определяется указанием пространства имен класса, переменную или метод которого нужно использовать.

Лаба №6.Ассоциация

Ассоциация 1:1.

Текст программы:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace lab6_1k1

{

class Program

{

   //1: 1

   //ссылка используется

   //в D на E. и наоборот

   class D

   {

       public D() { Console.WriteLine("Constructor D"); }

 

~D() { }

       public E e { set; get; }

       public int F() { return 0; }

   }

 

   class E

   {

       public E()

       {

           Console.WriteLine("Constructor E");

           this.k = 1;

       }

       ~E() { }

       public D d { set; get; }

       public int k { set; get; }

       public int F() { return 1; }

   }

 

   static void Main(string[] args)

   {

       //создаются объекты

       D d = new D();

       E e = new E();

 

       //пока что эти объекты классов не связаны. их надо связать с помощью ассоциации

 

       Console.WriteLine("d.F() = {0}", d.F());

       Console.WriteLine("d.F() = {0}", e.F());

       Console.WriteLine();

 

       //ассоциация

       //объект e обращается к атрибуту доступа класса D и подставляет ему объект d

       e.d = d;

       //аналогично для объекта d

       d.e = e;

 

       Console.WriteLine("d.F() = {0}", d.F());

       Console.WriteLine("e.F() = {0}", e.F());

       Console.WriteLine();

           

       //обращение к функциям. нельзя так делать, пока не проведена ассоциация.

       Console.WriteLine("e.d.F = {0}", e.d.F());

       Console.WriteLine("d.e.F = {0}", d.e.F());

       Console.WriteLine();

 

       Console.WriteLine("d.e.k = {0}", d.e.k);

       e.d.e.k = 2;

        Console.WriteLine();

       Console.WriteLine("e.d.e.k = {0}", e.d.e.k);

       e.d.e.d.e.k = 3;

       Console.WriteLine("e.d.e.d.e.k = {0}", e.d.e.d.e.k);

       Console.ReadKey();

   }

}

}

Вывод: Ассоциация - двусторонняя зависимость. При ассоциации взаимодействующие объекты, между собой условно находятся на одном уровне. Ни один из объектов не имеет превосходства над другим, и из любого можно получить другой, связанный с ним объект.

 

Ассоциация 1:N

Текст программы:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace lab6_1kN

{

class Program

{

   class D

   {

       //конструктор номер 1

       public D()

       {

           this.e = new E[N];

           Console.WriteLine("Constructor1 D");

       }

       //конструктор номер 2, если N вводится пользователем, например

       public D(int N)

       {

           this.N = N;

           this.e = new E[N];//массив скрытых ссылок на объекты класса E

           Console.WriteLine("Constructor2 D");

       }

 

       ~D() { Console.WriteLine("Ddestructor D"); }

 

       public void setE(E e) // создание ассоциации

       {

           //ассоциация

           if (size < N)

           {

               Console.WriteLine("Proverka");

               this.e[size] = e;

               size++;

           }

       }

 

       //метод, позволяющий просматривать последовательно объекты класса E, связанные с объектом класса D

       public E getNext(int index)

       {

           if (index < size)

           {

              return e[index];//возвращаем ссылку

           }

           return null;

       }

 

       private E[] e = null;

       private int size = 0;

       //количество объектов класса E

       private int N = 7;

   }

 

   class E

   {

       //конструктор 1

       public E() { Console.WriteLine("Constructor1 E"); }

 

 

       //конструктор 2

       public E(D d)

       {

           d.setE(this);

           Console.WriteLine("Constructor2 E");

       }

       ~E() { Console.WriteLine("Destructor E"); }

 

       public int f() { return v; }

       private int v = 11;

       public D d { set; get; }

   }

 

   static void Main(string[] args)

   {

       D d1 = new D(); //создание объекта класса D с помощью конструктора номер 1

       D d2 = new D(8);//создание объекта класса D с помощью конструктора номер 2

           

       E e1 = new E();

       d1.setE(e1);// установка для N-ого ассоциации

       E e3 = new E();

       d1.setE(e3);// установка для N-ого ассоциации

       E e4 = new E();

       d1.setE(e4);

 

       e1.d = d1;// обычная установка ассоциации(объект е1 обращается к атрибуту доступа класса D и присваивает ему d1)

       Console.WriteLine("e1.d = {0}", e1.d);

       d1.getNext(1).d = d1; // здесь мы присвоили ассоциацию как d1.e[1].d1 и что то подобного типа (под вопросом?)

           

 

       Console.WriteLine("e1.d.getNext(0) = {0}", e1.d.getNext(0));

       Console.WriteLine(" d1.getNext(0).f() = {0}", d1.getNext(0).f());

       Console.WriteLine(" d1.getNext(1) = {0}", d1.getNext(1));

       Console.WriteLine(" d1.getNext(2) = {0}", d1.getNext(2));

       Console.WriteLine(" d1.getNext(1).d = {0}", d1.getNext(1).d);

       E e2 = new E(d1); // (?)

       e2.d = d1;

       Console.WriteLine(" e2.d.getNext(0) = {0}", e2.d.getNext(0));

 

       Console.ReadKey();

   }

}

}

 

 

Результат работы программы:


Вывод:
В ассоциации 1: N каждый из N объектов указывает на 1, общий для всех, объект, который в свою очередь имеет N указателей на другие объекты. При этом, из одного объекта группы, с помощью общего можно перейти к другим объектам этой группы.


 

Общность.

Текст программы:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace Lab7_friend

{

class Program

{

   static class D

   {

       //public static D() { }// не может содержать конструкторы

       public static int F() { return 7; } // Содержит только статические член

       //public void f() { Console.WriteLine("Нельзя это использовать в статическом классе..."); }

   }// Статический класс в основном такой же, как и нестатический класс, но имеется одно отличие: нельзя создавать экземпляры статического класса.

   class F

   {

       public static int R() { return 10; } // а так можно в обычном классе использовать статические функции

       private static int F1() { return 1; }

   }// статические функции можно использовать в других классах и функциях и они также будут доступны везде

   // скрыть их можно с помощью модификатора доступа private

 

   class E

   {

       public E() { }

       ~E() { }

       public void me() { Console.WriteLine("class D function F = {0}", D.F()); }

 

       public void ME() { Console.WriteLine("class F function R = {0}", F.R()); }

   }

   static void Main(string[] args)

   {

       F f = new F();

       E e = new E();

       e.me();

       //нельзя сделать D d = new D();

       D.F();

       Console.WriteLine("class F function R = {0}", F.R());

       e.ME();

 

       //Console.Readkey() — Console - класс. а ReadKey() - статическая функция

       Console.ReadKey();

   }

}

}

Результат работы программы:


Вывод:
Использование общности позволяет одному объекту взаимодействовать со всеми методами и членами второго, если первый объект по отношению ко второму объявляется другом. Также, чтобы открыть доступ функциям к данным объекта. они могут быть объявлены дружественными.

 

Лаба №8. Конкретизация.

Текст программы:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace Lab8

{

public interface IA

{

   void F();

}

class A: IA

{

   public void F() { Console.WriteLine("Привет"); }

}

class U<T> where T:class// с помощью where T: class мы можем ограничить тип Т. в данном случае здесь по классу, т.е. в Т можем конкретизировать только классы.

   // здесь задача не используя наследования, с помощью этого класса обратиться и вызвать метод другого класса

{      // при использовании категории использование, он будет выдавать ошибку.

   //поэтому я определил интерфейс и сделал преобразования типа к интерфейсу для универсального параметра

   public void F1() { Console.WriteLine("Как дела?"); }

   public U(T t) { this.t = t; }

   public T t { get; set; }

   //IA ia;// = new A();

   public void F()

   {

       Console.WriteLine(t is IA);

       Console.WriteLine(t);// вывод что это вообще за параметр

       if (t is IA)

       {

           IA ia = (IA)t;// делаем преобразование типа к интерфейсу

           ia.F();// вызов функции в классе А F()

       }

 

   }

 

}

class IdAccount<T>

{

   public IdAccount(T name, int Sum) { this._Sum = Sum; this.namet = name; }

   public T namet;

   public int _Sum;

}

class Swap<T>// здесь Т универсальный параметр, он позволяет указать, какой тип здесь будет использоваться

{

   public void FSwap(ref T x, ref T y)

   {

       t = x;

       x = y;

       y = t;

   }

   public T t;

 

}

class Program

{

   static void Main(string[] args)

   {

       Swap<int> swap = new Swap<int>();// здесь мы используем объект типа int

       int x = 5;

       int y = 6;

       Console.WriteLine("x = {0} y = {1}", x, y);

       swap.FSwap(ref x, ref y);// передача параметров по ссылке. при передачи по значению, в метод передается только копия, а здесь передается ссылка на саму переменную в память

       Console.WriteLine("x = {0} y = {1}", x, y);

 

       IdAccount<string> idAccount1 = new IdAccount<string>("Ваня", 5000);

       IdAccount<int> idAccount2 = new IdAccount<int>(15954, 70000);

 

       Console.WriteLine("{0} {1}", idAccount1.namet, idAccount1._Sum);

       Console.WriteLine("{0} {1}", idAccount2.namet, idAccount2._Sum);

 

       A a = new A();

       //Console.WriteLine(a is IA);

       U<A> u = new U<A>(a);// передача по ссылке объекта в конструктор. здесь мы передали класс А в параметр типа.

       //U<A> u = new U<A>();

       //u.t = a;// связываем объекты двух классов u и a.

       u.F();

       Console.ReadKey();

   }

}

}

 

Вывод: Мы конкретизируем классы и функции для работы с объектами, типы которых заранее не определены. С каким(и) именно типам(и) придется работать определяется в момент вызова – имя типа настраивает функцию\класс для работы. Это нужно для повторного использования кода (повышает гранулярность программного кода).

Лаба №9. Анонимные функции.

Делегаты.

Текст программы:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace lab9._1

{

class Program

{

   public delegate void Str(string s);//делегаты - это указатели на методы и с помощью делегатов мы можем вызвать данные методы.

   public delegate int Sum(int x, int y);// сначала идёт ключевое слово delegate, потому тип возращаемого типа, название и параметры в скобках.

   public delegate void Ob();

 

   static void Main(string[] args)

   {

       Str str = null;// создаем переменную делегата

       str = MessageShow;// присваиваем адрес метода

       MessageShow("Привет");// он обратится к статическому методу в этом классе и выведет строчку, т.к. мы передаем в качестве параметра строку

       Sum sum = SumF;

       Console.WriteLine($"SumF(20, 17) = {SumF(20, 17)}");

       Console.WriteLine();

       Ob ob = null;

       ob += Pr;// к этой переменной делегата прибавим строчку для вывода

       ob();// Привет

       Str str1 = new Str(MessageShow);// ещё один способ передачи методов, создание объекта делегата с помощью конструктора в который передается нужный метод

       MessageShow("Как дела");

 

       Console.WriteLine();

       //ob = ob + Ds; // или ob += Ds;

       //ob();// Привет, Всё с тобой понятно, пока.

       //Console.WriteLine();

 

       Ob s = delegate ()// создание анонимного метода

       {//создание анонимного метода начинается с ключевого слова delegate, после которого в скобках передаётся количество параметров и идёт тело метода

           Console.WriteLine("Как погода");

       };

       s();

       Console.WriteLine();

       MessaShow2("Азаза", delegate (string tr)

       {

           Console.WriteLine(tr);

       });

       ob -= Pr;

       Console.WriteLine();

       ob += Ds;

       ob();

       Console.ReadKey();

   }

   public static void MessaShow2(string s, Str str)

   {

       str(s);

   }

   public static void MessageShow(string s)

   {

       Console.WriteLine(s);

   }

   public static int SumF(int x, int y)

   {

       return x + y;

   }

   public static void Pr()

   {

       Console.WriteLine("Помогите");

   }

   public static void Ds()

   {

       Console.WriteLine("Пожалуйста");

   }

}

} Результат работы программы:

Вывод: Для определения делегата используется ключевое слово delegate, после которого идет сигнатура. Для использования делегата объявляется объект этого делегата. Объекту данного класса сигнатур можно присвоить метод со сходной сигнатурой. Для объектов класса сигнатур возможна операция декремента/инкремента. Также можно использовать анонимные делегаты путём объявления объекта класса сигнатур и присваивания ему анонимного метода со сходной у делегата сигнатурой.Делегаты можно передавать в качестве аргументоа методу, что довольно удобно.Использование делегатов позволяет добиться более адекватного моделирования и повторного использования кода.

 

Лямбда-выражения

Текст программы:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace lab9._2

{

class Program

{

   delegate void N();

   delegate string Str(string s);

   delegate int Sum(int x, int y);

   delegate int Sum1(int x);

   delegate int X(ref int x);

 

   static void Main(string[] args)

   {// лямбда выражения создаются с помощью делегатов

       Sum sum = (x, y) => x + y;// самое простое лямбда выражение. В скобках передается количество параметров, после знака => выолняется блок выражений

       Console.WriteLine($"sum(10,2) = {sum(10, 2)}");// параметры в скобках должны соответствовать типам и количеству параметров в делегате

       Console.WriteLine();

 

       Sum1 sum1 = x => x++;

       Console.WriteLine($"sum1(1) = {sum1(1)}");

       Console.WriteLine();

 

       Str str = (s) => "Ну наконец-то";

       Console.WriteLine(str);

       Console.WriteLine();

 

       N n = () => Console.WriteLine("А эти лямбда выражения прикольные");

       n();

       Console.WriteLine();

 

       N n1 = () => Message();// создали объект n1 который вызывает метод Message()

          n1();              // Ну привет

       Console.WriteLine();

 

       int n2 = 19;

       X x1 = (ref int r) => r++; // при передаче по ссылке нужно указывать и в делегате что мы передаем по ссылке

       Console.WriteLine($"x1(ref n2) = {x1(ref n2)}");

 

 

       List<int> arr = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

       Console.WriteLine(arr.First<int>());// вывод первого элемента массива в листе

       arr.Add(15);

       arr.ForEach(delegate (int i)// использование перебора элементов массива с помощью делегатов и вывод их

       {

           Console.Write($"{i} ");

       });

       arr.ForEach((i) => Console.WriteLine(i));// использование перебора элементов массива с помощью лямбда-выражений и вывод их

 

       Console.ReadKey();

   }

   public static void Message()

   {

       Console.WriteLine("Ну привет");

   }

 

}

}

Результат работы программы:

Вывод: Лямбда-выражения представляют упрощенную запись анонимных методов. Лямбда-выражения позволяют создать емкие лаконичные методы, которые могут возвращать некоторое значение и которые можно передать в качестве параметров в другие методы. Ламбда-выражения имеют следующий синтаксис: слева определяется список параметров, в середине лямбда-оператор =>, а справа блок выражений, использующий эти параметры: (список_параметров) => выражение. Как и делегаты, лямбда-выражения можно передавать в качестве аргументов методу для тех параметров, которые представляют делегат, что довольно удобно. Как и делегаты, лямбда-выражения позволяют добиться повторного использования кода и адекватного моделирования.

 

События.

Используя события, создадим маленький тест для проверки приветствия на английском языке.

Текст программы:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace lab4_1

{

class Student

{

   public delegate void EventStudentHandler(string s);

   public event EventStudentHandler True;// события объявляются с помощью ключевого слова event, после которого следует тип делегата и потом название события

   public event EventStudentHandler False;

   public event EventStudentHandler Vvod;

   public void vvod()

   {

       if (Vvod!= null)

           Vvod("Введите приветствие на английском языке: ");// определив событие, мы можем вызвать его как метод, используя имя события

   }

   public void TF(string s)

   {

       if (s == "hi" || s == "hello")

       {

           if (True!= null)

           {

               Console.ForegroundColor = ConsoleColor.Blue;// устанавливаем цвет фона на вывод события. Это синий

               True("Это правильно!");

               Console.ResetColor();// сброс цвета

           }               

       }

       else

       {

           if (False!= null)

           {

               Console.ForegroundColor = ConsoleColor.Red;

               False("Это неправильно!");

               Console.ResetColor();

           }

       }

   }

}

class Program

{

   static void Main(string[] args)

   {

       Student student = new Student();

       student.Vvod += Show_Message1; // добавление обработчика события. он добавляется только так: {событие} += {обработчик события}. также и удаление -=

       student.True += Show_Message;// нередко в качестве обработчиков события применяются Методы

       student.False += Show_Message;// каждый обработчик событий должен соответствовать по списку параметров и возвращаемому типу делегата

       for (;;)// здесь он для примера выводов обработчиков

       {

           student.vvod();

           string s = Console.ReadLine();

           if (s == "exit") break;

           student.TF(s);

               

               

       }

       Console.ReadKey();

   }

   public static void Show_Message(string s)

   {



Поделиться:


Последнее изменение этой страницы: 2021-07-18; просмотров: 124; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.118.26.90 (0.768 с.)