1 / 13

Делегаты

Лекция 7. Делегаты. Зачем нужны делегаты. И данные , и код располагаются в памяти компьютера по определенным адресам. Передача адресов данных в C# происходит при помощи ссылок. Передача адресов кода в C# происходит при помощи делегатов.

barid
Download Presentation

Делегаты

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Лекция 7 Делегаты

  2. Зачем нужны делегаты И данные, и код располагаются в памяти компьютера по определенным адресам. Передача адресов данных в C# происходит при помощи ссылок. Передача адресов кода в C# происходит при помощи делегатов. Делегат – это ссылка на метод, которая содержит не только его адрес, но и тип.

  3. Делегат – это объект • Делегат – это объект, который содержит в себе: • адрес метода, • типы параметров, • тип возвращаемого значения. • Делегаты могут хранить адреса как статическихметодов, так и на методов экземпляра. using System; delegatevoidD(inti); classProgram { staticvoid F(inti) { Console.WriteLine("fff"); } void G(inti) { Console.WriteLine("ggg"); } staticvoid Main(string[] args) { Dd = newD(F); // сокращенно: D d = F; d += newD((newProgram()).G); d += F; d(0); } } Говоря точнее, один делегат может хранить адреса сразу нескольких однотипных методов. F G F

  4. Применение делегатов Благодаря делегатам мы можем обращаться с методами, как с данными, т.е. передавать их в качестве параметров, возвращать из других методов, составлять из них массивы, коллекции и т.п. (т.е. программировать функционально). Пример Объявить метод, который получает вещественно число и произвольное количество функций типа double F(double). Метод должен вернуть результат последовательного применения всех функций к первому аргументу. Решение delegate double D(double x); double SeqFun(double x, paramsD[] funсs) {...}

  5. Как устроен делегат Пример делегата delegateboolMyDelegate(int x); Делегат наследует библиотечный класс MulticastDelegate. К методам предка компилятор добавляет метод Invoke(), из которого вызываются все целевые методы делегатав том порядке, как они туда попали. publicsealedclassMyDelegate : System.MulticastDelegate { publicMyDelegate(object target); publicbool Invoke(int x); publicIAsyncResultBeginInvoke(int x, AsyncCallbackcb, object state); publicboolEndInvoke(IAsyncResult result); }

  6. Обобщенные делегаты Если тип параметра делегата – object, он может ссылаться на любые функции с одним параметром, но это не будет безопасным. Более безопасны обобщенные делегаты, например: delegateTD<T>(Tx); classProgram { staticint f(inti) { returni + 1; } staticstring g(string s) { return s + "1"; } staticvoid Main(string[] args) { D<int> d1 = f; D<string> d2 = g; } }

  7. Функции высших порядков Это функции, параметрами которых являются другие функции. Задача Объявим функциюForEach, которая получает список и функцию-параметр и возвращает новый список, который получается из заданного путем поэлементного применения к нему функции-параметра. Например, задан список { 1, 2, 3, 4, 5} и функция "y = 10 * x". ForEachдолжна вернуть новый список { 10, 20, 30, 40, 50}. Если функция-параметр "y = x * x", тофункция ForEachвернет список {1, 4, 9, 16, 25} и т.д.

  8. Функция ForEach() delegate T Fun<T>(T x); staticList<T> ForEach<T>(List<T> list, Fun<T> f) { varresult = newList<T>(); foreach (T x inlist) result.Add(f(x)); returnresult; } Замечание. Если заменить тип первого параметра на IEnumerable<T>, функцию можно будет применять не только к спискам, но и к массивам. double[] m = { 1, 4, 16 }; var r = ForEach(m, Math.Sqrt);

  9. Функция Where Объявить статический обобщенный метод, который получает список List<T> и обобщенный делегат bool Predicate<T>(T x) и возвращает новый список, в котором содержатся все элементы исходного списка, удовлетворяющие условию Predicate. staticList<T> Where<T>(List<T> list, Predicate<T> pre) { varresult= newList<T>(); foreach (T x inlist) if(pre(x)) result.Add(x); returnresult; } staticbool Pre1(double x) { return x > 10; } staticvoid Main() { List<double> m = newList<double> { 1, 4, 16 }; var r = Where(m, Pre1); }

  10. Анонимные делегаты При вызове функции Where ее первый аргумент можно сделать анонимным. staticbool Pre1(double x) { return x > 10; } staticvoid Main(string[] args) { var r = Where(newList<double> { 1, 4, 16 }, Pre1); } Анонимнымможно сделать и второй аргумент. staticvoid Main(string[] args) { List<double> m = newList<double> { 1, 4, 16 }; var r = Where(m, delegate(double x) { return x > 10; }); } λ

  11. Лямбда-выражения Лямбда-выражение в С# - это безымянный экземпляр делегата. var r = Where(m, delegate(double x) { return x > 10; }); var r = Where(m, x => x > 10 ); Лямбда-выражения пришли в С# из функционального программирования, а туда – из математической логики.

  12. Библиотечные делегаты Func и Action Лямбда-выражения экономят код при вызове функций, а библиотечные делегаты – при их объявлении. До слайда: После слайда: delegate T Fun<T>(T x); staticList<T> ForEach<T>(List<T> list, Fun<T> f) delegateboolPre<T>(T x); staticList<T> Where<T>(List<T> list, Pre<T> f) staticList<T> ForEach<T>(List<T> list, Func<T, T> f) staticList<T> Where<T>(List<T> list, Func<T, bool> f)

  13. Самостоятельно Объявить делегат, который ссылается на произвольную бинарную операцию над целыми числами, т.е. int Op(intx, int y). Создать объект делегата для операции взятия остатка по модулю и вызвать его синхронно и асинхронно.

More Related