Advanced C#. Part 2

49
eleks.com eleks.com Advanced C#. Part 2 Events and Delegates. Anonimous methods. Lamda Expressions. LINQ

Transcript of Advanced C#. Part 2

Page 1: Advanced C#. Part 2

eleks.com eleks.com

Advanced C#. Part 2Events and Delegates. Anonimous methods. Lamda Expressions. LINQ

Page 2: Advanced C#. Part 2

Делегати

public abstract class Delegate : ICloneable, ISerializable

Page 3: Advanced C#. Part 2

Делегати

Делегати – вказівники на методи, які інкапсулюють справжні вказівники і надають

зручні сервіси для роботи з ними.

Делегати є об’єктами типу System.Delegate або System.MulticastDelegate.

System.Delegate (obsolete) - тільки одне посилання на метод

System.MulticastDelegate – кілька посилань на метод, які викликаються по ланцюжку

Page 4: Advanced C#. Part 2

При описі делегати ми вказуємо прототип методу, на який будуть посилатись

екземпляри даного делегата.

public delegate void MyDelegate (string s);

де MyDelegate – назва делегата (назва типу), void – тип що мають повертати функції,

string – тип аргумента функцій

Сам по собі делегат являється типом і жодних посилань на метод містити не може і,

відповідно, не може використовуватись для звернення до них.

Оголошення делегата

Page 5: Advanced C#. Part 2

MyDelegate delegate1 = new MyDelegate(MyHandler);

Де MyDelegate – тип делегата, delegate1 – екземпляр делегата, який буде створений

в результаті виконання конструкції, MyHendler – метод, на який буде посилатись

делегат.

Після створення делегата ми можемо звертатись до методів, на які він посилається.

До делегата можна звертатись як до самого метода:

delegate1(“Hello World”);

Створення екземпляра делегата

Page 6: Advanced C#. Part 2

eleks.com

Демонстрація 1• Найпростіший приклад роботи з делегатами

Page 7: Advanced C#. Part 2
Page 8: Advanced C#. Part 2

Методи в .Net діляться на статичні (static) і екземплярні (instance).

Щоб викликати екземплярний метод делегату потрібно знати посилання на об’єкт до

якого прив’язаний конкретний метод. Це посилання зберігається в самому обєкті

делегата і вказується при його створенні.

MyDelegate myDelegate = new MyDelegate(myClass.MyHandler);

Де myClass – посилання на екземпляр обєкта,який повинен використовуватися при

зверненні до методу MyHandler

Делегат і екземплярні методи

Page 9: Advanced C#. Part 2

eleks.com

Демонстрація 2• Делегат і екземплярний метод

Page 10: Advanced C#. Part 2

• Коваріантність – дозволяє присвоїти делегату метод, тип результату якого може

бути клас дочірній до класу, вказаного в делегаті.

• Контрваріантність - дозволяє присвоїти делегату метод, тип результату якого

може бути клас батьківський до класу, вказаного в делегаті.

Коваріантність і контрваріантність

Page 11: Advanced C#. Part 2

Властивості

Щоб викликати екземплярний метод делегату потрібно знати посилання на об’єкт до

якого прив’язаний конкретний метод. Це посилання зберігається в самому обєкті

делегата і вказується при його створенні.

public MethodInfo Method { get; }

public object Target { get; }

MulticastDelegate

Повертає метод, на який посилається делегат

Повертає об’єкт, до якого прив’язаний метод, на який посилається делегат

Page 12: Advanced C#. Part 2

MulticastDelegate.Method

Якщо делегат мітить більше одного посилання на функцію, то властивість повертатиме

останнє добавлене посилання.

MulticastDelegate.Target

Якщо делегат посилається на статичний метод , то властивість поверне null. Якщо

делегат містить більше одного посилання на функцію, то властивість поверне об’єкт,

пов’язаний з останнім в черзі методом.

MulticastDelegate

Page 13: Advanced C#. Part 2

eleks.com

Демонстрація 3• Використання властивостей делегата

Page 14: Advanced C#. Part 2

Equality and Inequality Operators

Оператори рівності ( = = ) і нерівності ( ! = ) дозволяє визначити рівність делегатів, чи

посилаються вони на одну й туж саму функцію. При порівнянні враховується не тільки

метод, на який посилається делегат але й посилання на об’єкт, з яким зв’язаний

метод.

Оператори порівняння делегатів

Page 15: Advanced C#. Part 2

• Delegate.Combine – обєднує два або більше делегата, створюючи новий делегат,

список викликів якого включає списки обєднуваних делегатів. Вихідні делегати не

модифікуються.

• Delegate.Remove – видаляє список викликів одного делегата з списку викликів

іншого. При цьому створюється новий делегат, список викликів якого являє собою

результат видалення. Вихідні делегати не модифікуються.

Методи делегатів

Page 16: Advanced C#. Part 2

Ви можете оперувати з делегатами за допомогою звичайних операцій додавання і

віднімання ( +, -, + =, - = ). При цьому компілятор автоматично буде генерувати код, який

звертатиметься до методів Combine i Remove.

• Delegate.DynamicInvoke – дозволяє динамічно звернутись до функцій, повязаних з

делегатом.

Методи делегатів

Page 17: Advanced C#. Part 2

• MulticastDelegate.GetInvocationList – повертає список делегатів, які знаходяться в

списку виклику делегатів

Корисність:

Коли в списку більше однієї функції, і вони повертають значення. Через Invoke ми

отримаємо тільки значення останньої.

Якщо якась з функцій впаде, то робота метода Invoke буде перервана і решта

функцій буде не викликана.

Методи делегатів

Page 18: Advanced C#. Part 2

Нульові делегатиmyDelegate = new MyDelegate(SomeMethod); myDelegate -= new MyDelegate(SomeMethod);

В результаті ми отримаємо не пустий делегат, а null

Тому коли значення делегата невідоме варто влаштовувати перевірку

if (myDelegate != null)myDelegate("Hello, World!");

Page 19: Advanced C#. Part 2

Вбудовані делегати:

delegate bool Predicate();delegate bool Predicate<T1>(T1 parameter1);delegate bool Predicate<T1, T2>(T1 parameter1, T2 paremter2);delegate bool Predicate<T1, T2, T3>(T2 parameter1, T2 paremter2, T3 parameter3);

delegate T Func<T>(T returnType);delegate T Func<T, T1>(T returnType, T1 parameter1);delegate T Func<T, T1, T2>(T returnType, T1 parameter1, T2 paremter2);delegate T Func<T T1, T2, T3>(T returnType, T1 parameter1, T2 paremter2, T3 parameter3);

delegate void Action();delegate void Action<T1>(T1 parameter1);delegate void Action<T1, T2>(T1 parameter1, T2 paremter2);delegate void Action<T1, T2, T3>(T1 parameter1, T2 paremter2, T3 parameter3);

Page 20: Advanced C#. Part 2

eleks.com

Демонстрація 4• GetInvocationList

Page 21: Advanced C#. Part 2

eleks.com

Переривчик 5хв

Page 22: Advanced C#. Part 2

delegate void Anonim(); // Сигнатура делегата

// використовуємо анонімний методAnonim anonim = delegate{

DirectoryInfo dir = new DirectoryInfo("D:\\");foreach (DirectoryInfo d in dir.GetDirectories())Console.WriteLine(d.Name);

};

anonim(); // запускаємо

Анонімні методи

Page 23: Advanced C#. Part 2

delegate void Anonim2( int start, int finish); // Сигнатура делегата

// використовуємо анонімний метод з параметрамиAnonim2 anonim2 = delegate(int a, int b) {

for (int i = a; i <= b; i++)Console.Write(«Опрацьовано {0} анкет." +

" Залишилось опрацювати {1}\n", i, b-i);};

anonim2(1, 10);

Анонімні методи з параметрами

Page 24: Advanced C#. Part 2

• Лямбда вираз – це анонімна функція, яка містить вирази та оператори і може бути

використана для створення делегатів або типів дерева виразів.

Параметри => Виконуваний код

( x, y ) => { return x + y }

( x, y ) – параметри, => - лямбда-оператор, { return x + y } - тіло методу

• Інший спосіб створення анонімних функцій, може бути присвоєний делегату

Лямбда вирази

Page 25: Advanced C#. Part 2

delegate int LambdaDelegate ( int step ); // сигнатура делегата

LambdaDelegate lambdaDel = a => ++a;// LambdaDelegate lambdaDel = (int a) => ++a;

int step = 1;int finish = 10;

while (step <= finish){Console.Write(«Оброблено {0} документів." + " залишилось {1}\n", step, finish - step);

step = lambdaDel(step);}

*Що буде якщо замінити ++а на а++ ?

Лямбда вирази (одиночні)

Page 26: Advanced C#. Part 2

Лямбда – оператори: (input parameters) => {statements;}

delegate int Power ( int change); // сигнатура делегата

Power lambdaDel = change =>{

if (change != 0)return change * change;

return 0;}

Console.WriteLine( Power ( 10 ) );

Лямбда оператори (блокові вирази)

Page 27: Advanced C#. Part 2

eleks.com

Summary

Page 28: Advanced C#. Part 2

Подія – автоматичне оповіщення про те, що сталась якась дія.

Події діють по настпному принципу: обєкт, який проявляє цікавіть до події, реєструє обробник цієї події.

Коли подія стається, викликаються всі зареєстровані обробники цієї події.

Обробники зазвичай представлені делегатами.

Події (Events)

Page 29: Advanced C#. Part 2

delegate void ClickHandler();

class Button

{

public ClickHandler Click;

void OnMsg(...)

{

switch(msg)

{

case WM_LBUTTONDOWN:

if (Click != null)

Click();

}

}

};

Приклад події на основі делегата

Page 30: Advanced C#. Part 2

event делегат_події ім’я_події;

Це введене в .NET поле-подія, яку автоматично вводить поле-делегат і два додаткових методі, які його обслуговують.

Події (Events)

Page 31: Advanced C#. Part 2

eleks.com

Демонстрація 5• Events

Page 32: Advanced C#. Part 2

eleks.com

Демонстрація 6• Екземплярний метод в якості обробника

Page 33: Advanced C#. Part 2

public event EventHandler<MyEventArgs> SomeEvent;

Середовище .NET надає вбудований узагальнений делегат EventHandler.

Рекомендується використовувати саме такий спосіб, а не визначати власний делегат.

EventHandler<TEventArgs>

Page 34: Advanced C#. Part 2

public delegate void EventHandler(

object sender, // Посилання на обєкт, що викликав подію

EventArgs e // Параметри, які описують подію

);

EventArgs не містить жодного поля, яке б передавало корисну інформацію.

Щоб передати додаткову інформацію через EventArgs, вводиться новий клас,

дочірний для нього.

Стандартний делегат

Page 35: Advanced C#. Part 2

eleks.com

Демонстрація 7• Складний приклад обробника подій

Page 36: Advanced C#. Part 2

• Дозволяють додавати нові методи в вже існуючі типи, без створення власного

класа.

• Метод розширення має доступ тільки до публічних членів класу.

• Якщо є вбудований метод і розширення, пріоритет надається вбудованому методу

• Методи розширення широко використовуються в LINQ.

Extension methods

Page 37: Advanced C#. Part 2

Examplepublic static class StringExtension{

public static int WordCount(this string str, char c){

int counter = 0;for (int i = 0; i<str.Length; i++){

if (str[i] == c)counter++;

}return counter;

}}

int i = s.WordCount(c);

Page 38: Advanced C#. Part 2

eleks.com

Демонстрація 8• Extension methods

Page 39: Advanced C#. Part 2

• LINQ (Language-Integrated Query) – мова інтегрованих запитів, дозволяє

видобувати інформацію з різних джерел даних.

• Працює з XML, SQL, ADO.NET, .NET Collections….

• Робить запит* частиною мови програмування.

• Компонент .NET Framework 3.5

*Запит – вираз, який дістає дані з джерела даних.

LINQ

Page 40: Advanced C#. Part 2

OthersC# VB.NET

.NET Language Integrated Query (LINQ)

LINQto SQL

LINQto Objects

LINQto XML

LINQto Datasets

LINQto Entities

LINQ data source providers

ADO.NET support for LINQ

Page 41: Advanced C#. Part 2

• Найпростіше визначення запита LINQ

from змінна in набір-обєктів

select змінна;

Запити LINQ

Page 42: Advanced C#. Part 2

• Обєкти використовують цикли і умови

foreach(Customer c in customers) if (c.Region == "UK") ...

• Бази даних використовують SQL

SELECT * FROM Customers WHERE Region='UK'

• XML використовую XPath/XQuery

//Customers/Customer[@Region='UK']

Запити без LINQ

Page 43: Advanced C#. Part 2

Запити з LINQ

var myCustomers = from c in customers

where c.Region == "UK"

select c;

var goodCusts = (from c in db.Customers

where c.PostCode.StartsWith("GY")

orderby c.Sales descending

select c).Skip(10).Take(10);

Page 44: Advanced C#. Part 2

Оператори LINQТип оператора запиту Оператори запиту

Обмеження Where, OfType

Проекція Select, SelectMany

Обєднання Join, GroupJoin

Конкатинація Concat

Сортування OrderBy, OrderByDescending, ThenBy, ThenByDescending, Reverse

Установка Distinct, Except, Intersect, Union

Групування GroupBy

Перетворення AsEnumerable, Cast, OfType, ToArray, ToDictionary, ToList, ToLookup

Порівняння SequenceEqual

Вибір елемента DefaultIfEmpty, ElementAt, ElementAtOrDefault, First, FirstOrDefault, Last, LastOrDefault, Single,

SingleOrDefault

Утворення Empty, Range, Repeat

Кількісне визначення All, Any, Contains

Агрегація Aggregate, Average, Count, LongCount, Max, Min, Sum

Разметка Skip, SkipWhile, Take, Takewhile

Page 45: Advanced C#. Part 2

• Крім стандартного синтаксису from .. in .. select для створення запиту

LINQ ми можемо застосовувати спеціальні методи розширення, які

визначені в інтерфейсі IEnumerable.

• Не кожен метод розширення має аналог серед операторів LINQ, в

цьому випадку можна застосовувати обидва підходи.

string[] teams = { "Баварія", "Борусія", "Реал Мадрид", "Манчестер Сіті", "Барселона" };

int number = (from t in teams where t.ToUpper().StartsWith("Б") select t).Count();

Методи розширення LINQ

Page 46: Advanced C#. Part 2

var contacts =

from c in customers

where c.City == "Hove"

select new { c.Name, c.Phone };

var contacts =

customers

.Where(c => c.City == "Hove")

.Select(c => new { c.Name, c.Phone });

Extension methods

Lambda expressions

Query expressions

Object initializersAnonymous types

Local variable type inference

Page 47: Advanced C#. Part 2

eleks.com

Демонстрація 10• Робота з LINQ

Page 48: Advanced C#. Part 2

© Denys Prylutskyi, 2015

Практичне завдання

Page 49: Advanced C#. Part 2

Рекомендована література

1. R. Sedgewick “Algorithms”

2. A. Troelsen “C# 6.0 and the .NET 4.6 Framework”

3. H. Schildt “C# 4.0 The Complete Reference”

4. J. Richter “CLR via C#”

5. J. Skeet “C# in Depth”

6. Stackoverflow.com