Коротко про Делегат:
Delegate -
це тип, який представляє собою посилання (ссилку) на методи з певним
списком параметрів і типом, що повертається. При створенні екземпляра
делегата цей екземпляр можна зв'язати з будь-яким методом з сумісною сигнатурою
і типом, що повертається. Метод можна викликати за допомогою екземпляра
делегата. Делегат - це reference тип.
Делегати використовують для передачі методів в якості аргументів інших методів.
Обробники подій - це методи, які викликані за допомогою делегатів.
Оголошення
делегата:
public delegate int CalculateSum(int x,
int y);
Делегати
є основою Подій (event).
Делегат
можна створити присвоївши йому метод з аналогічною сигнатурою або лямбда-вираз,
наприклад:
public delegate int CalculateSum(int
x, int y);
public class SomeDelegateClass
{
static int SomeClassMethod(int
x, int y)
{
return
x + y;
}
static void Main()
{
// Присвоюємо
делегату метод з класу з аналогічною сигнатурою
CalculateSum
myDelegate1 = SomeClassMethod;
// Викликаємо
наш делегат
int
result = myDelegate1(2, 2);
Console.WriteLine("Delegate 1 result = " +
result.ToString());
// Присвоюємо
делегату анонімний метод
CalculateSum
myDelegate2 = delegate(int
x, int y)
{
return 2 *
x + 2 * y; // можемо собі робити якусь іншу дію
};
result = myDelegate2(2, 2);
Console.WriteLine("Delegate 2 result = " +
result.ToString());
// Присвоюємо
делегату лямбда-вираз
CalculateSum
myDelegate3 = (x, y) => 3 * x + 3 * y;
result = myDelegate3(2, 2);
Console.WriteLine("Delegate 2 result = " +
result.ToString());
Console.ReadKey();
}
}
Делегат
можна оголошувати як в межах класу, так і поза його межами.
Оскільки створений делегат є об'єктом, то його можна передавати як параметр або
присвоювати проперті.
Делегати
можуть ссилатись не на один метод, а на декілька одразу.
Коротко
про Евент:
Event - це сутність, що
дозволяє класу або об'єкту повідомляти інші класи або об'єкти про виникнення
певних ситуацій. Відповідно ті класи або об'єкти, що отримали повідомлення
можуть якось на них реагувати.
Оголошення
евента:
public event EventHandler
SomethingChanged;
В
даному оголошення EventHandler – це тип-делегат. Отже робимо
висновки, що основою роботи евентів є делегати.
Ми
звикли оголошувати евент таким чином:
public class SomeEventClass
{
public event EventHandler
SomethingChanged;
}
Компілятор
в свою чергу транслює це оголошення в такий код:
public class SomeEventClass
{
EventHandler
somethingChanged;
public event EventHandler
SomethingChanged
{
add
{
EventHandler
eventHandler = this.somethingChanged;
EventHandler
comparand;
do
{
comparand = eventHandler;
eventHandler = Interlocked.CompareExchange<EventHandler>
(ref this.somethingChanged,
comparand + value, comparand);
} while
(eventHandler != comparand);
}
remove
{
EventHandler
eventHandler = this.somethingChanged;
EventHandler
comparand;
do
{
comparand = eventHandler;
eventHandler = Interlocked.CompareExchange<EventHandler>
(ref this.somethingChanged,
comparand - value, comparand);
} while
(eventHandler != comparand);
}
}
}
При
явній реалізації евента програміст сам оголошує делегат для евента і вручну
додає та удаляє підписників через блоки add/remove (оба блока повинні бути
обов'язково).
Евент
можна оголошувати тільки в межах класу.
Стандартними
типами подій є
- EventHandler - у випадку коли не
потрібно аргументи події передавати
- EventHandler<TEventArgs>- у випадку коли
аргументи події потрібні, тоді ми створюємо клас, який наслідується
від EventArgs.
Щоб
підписатись або відписатись до/від евента ми використовуємо += та -=
Приклад
створення свого евента:
// Створюємо кастомний аргумент
public class MessageEventArgs
: EventArgs
{
public string Message { get;
private set; }
public
MessageEventArgs(string message)
{
Message = message;
}
}
// Створюємо клас,
що буде містити евент
public class Oksana
{
// Створюємо делегат
- тип нашого евента і в параметрах передаємо аргумент
public delegate void TalkEventHandler(Oksana
sender, MessageEventArgs e);
// Створюємо евент
типу делегату, що ми створили
public event TalkEventHandler OksanaSaid;
// Будемо у циклі
постійно рейзати наш евент
public void StartTalk()
{
while
(true)
{
if
(OksanaSaid != null)
{
MessageEventArgs
message = new MessageEventArgs(
"Bla bla bla at " +
DateTime.Now.ToString());
OksanaSaid(this, message);
}
}
}
}
public class Student
{
// Підписуємось
на евент
public void Subscribe(Oksana
oksana)
{
oksana.OksanaSaid +=
new Oksana.TalkEventHandler(LearnedThatOksanaSaid);
}
// Обробляємо
евент коли він викличеться в класі Oksana
private void LearnedThatOksanaSaid(Oksana
sender, MessageEventArgs e)
{
Console.WriteLine("Learned Oksana's lesson: " +
e.Message);
}
}
public class SomeEventClass
{
static void Main()
{
Oksana
oksana = new Oksana();
Student
student = new Student();
student.Subscribe(oksana);
oksana.StartTalk();
}
}
Отже яка ж різниця між Event ти Delegate
- Event – це той самий Delegate, який наділений деякими
властивостями за допомогою слова event.
- І Event і Delegate можна оголосити полем класу, але на відміну від
Delegate, Event не може бути локальною змінною методу.
- Event не можна запустити поза межами класу, в якому він був
оголошений.
- Event завжди оголошується як поле, а не
властивість (якщо не враховувати add/remove).
І на останок декілька корисних лінків
Delegate - це тип, який представляє собою посилання (ссилку) на методи з певним списком параметрів і типом, що повертається. При створенні екземпляра делегата цей екземпляр можна зв'язати з будь-яким методом з сумісною сигнатурою і типом, що повертається. Метод можна викликати за допомогою екземпляра делегата. Делегат - це reference тип.
Делегати використовують для передачі методів в якості аргументів інших методів. Обробники подій - це методи, які викликані за допомогою делегатів.
Оголошення
делегата:
public delegate int CalculateSum(int x,
int y);
Делегати
є основою Подій (event).
Делегат
можна створити присвоївши йому метод з аналогічною сигнатурою або лямбда-вираз,
наприклад:
public delegate int CalculateSum(int
x, int y);
public class SomeDelegateClass
{
static int SomeClassMethod(int
x, int y)
{
return
x + y;
}
static void Main()
{
// Присвоюємо
делегату метод з класу з аналогічною сигнатурою
CalculateSum
myDelegate1 = SomeClassMethod;
// Викликаємо
наш делегат
int
result = myDelegate1(2, 2);
Console.WriteLine("Delegate 1 result = " +
result.ToString());
// Присвоюємо
делегату анонімний метод
CalculateSum
myDelegate2 = delegate(int
x, int y)
{
return 2 *
x + 2 * y; // можемо собі робити якусь іншу дію
};
result = myDelegate2(2, 2);
Console.WriteLine("Delegate 2 result = " +
result.ToString());
// Присвоюємо
делегату лямбда-вираз
CalculateSum
myDelegate3 = (x, y) => 3 * x + 3 * y;
result = myDelegate3(2, 2);
Console.WriteLine("Delegate 2 result = " +
result.ToString());
Console.ReadKey();
}
}
Делегат
можна оголошувати як в межах класу, так і поза його межами.
Оскільки створений делегат є об'єктом, то його можна передавати як параметр або присвоювати проперті.
Оскільки створений делегат є об'єктом, то його можна передавати як параметр або присвоювати проперті.
Делегати
можуть ссилатись не на один метод, а на декілька одразу.
Коротко
про Евент:
Event - це сутність, що дозволяє класу або об'єкту повідомляти інші класи або об'єкти про виникнення певних ситуацій. Відповідно ті класи або об'єкти, що отримали повідомлення можуть якось на них реагувати.
Оголошення
евента:
public event EventHandler
SomethingChanged;
В
даному оголошення EventHandler – це тип-делегат. Отже робимо
висновки, що основою роботи евентів є делегати.
Ми
звикли оголошувати евент таким чином:
public class SomeEventClass
{
public event EventHandler
SomethingChanged;
}
Компілятор
в свою чергу транслює це оголошення в такий код:
public class SomeEventClass
{
EventHandler
somethingChanged;
public event EventHandler
SomethingChanged
{
add
{
EventHandler
eventHandler = this.somethingChanged;
EventHandler
comparand;
do
{
comparand = eventHandler;
eventHandler = Interlocked.CompareExchange<EventHandler>
(ref this.somethingChanged,
comparand + value, comparand);
} while
(eventHandler != comparand);
}
remove
{
EventHandler
eventHandler = this.somethingChanged;
EventHandler
comparand;
do
{
comparand = eventHandler;
eventHandler = Interlocked.CompareExchange<EventHandler>
(ref this.somethingChanged,
comparand - value, comparand);
} while
(eventHandler != comparand);
}
}
}
При
явній реалізації евента програміст сам оголошує делегат для евента і вручну
додає та удаляє підписників через блоки add/remove (оба блока повинні бути
обов'язково).
Евент
можна оголошувати тільки в межах класу.
Стандартними
типами подій є
- EventHandler - у випадку коли не
потрібно аргументи події передавати
- EventHandler<TEventArgs>- у випадку коли
аргументи події потрібні, тоді ми створюємо клас, який наслідується
від EventArgs.
Щоб
підписатись або відписатись до/від евента ми використовуємо += та -=
Приклад
створення свого евента:
// Створюємо кастомний аргумент
public class MessageEventArgs
: EventArgs
{
public string Message { get;
private set; }
public
MessageEventArgs(string message)
{
Message = message;
}
}
// Створюємо клас,
що буде містити евент
public class Oksana
{
// Створюємо делегат
- тип нашого евента і в параметрах передаємо аргумент
public delegate void TalkEventHandler(Oksana
sender, MessageEventArgs e);
// Створюємо евент
типу делегату, що ми створили
public event TalkEventHandler OksanaSaid;
// Будемо у циклі
постійно рейзати наш евент
public void StartTalk()
{
while
(true)
{
if
(OksanaSaid != null)
{
MessageEventArgs
message = new MessageEventArgs(
"Bla bla bla at " +
DateTime.Now.ToString());
OksanaSaid(this, message);
}
}
}
}
public class Student
{
// Підписуємось
на евент
public void Subscribe(Oksana
oksana)
{
oksana.OksanaSaid +=
new Oksana.TalkEventHandler(LearnedThatOksanaSaid);
new Oksana.TalkEventHandler(LearnedThatOksanaSaid);
}
// Обробляємо
евент коли він викличеться в класі Oksana
private void LearnedThatOksanaSaid(Oksana
sender, MessageEventArgs e)
{
Console.WriteLine("Learned Oksana's lesson: " +
e.Message);
}
}
public class SomeEventClass
{
static void Main()
{
Oksana
oksana = new Oksana();
Student
student = new Student();
student.Subscribe(oksana);
oksana.StartTalk();
}
}
Отже яка ж різниця між Event ти Delegate
- Event – це той самий Delegate, який наділений деякими властивостями за допомогою слова event.
- І Event і Delegate можна оголосити полем класу, але на відміну від Delegate, Event не може бути локальною змінною методу.
- Event не можна запустити поза межами класу, в якому він був оголошений.
- Event завжди оголошується як поле, а не властивість (якщо не враховувати add/remove).
І на останок декілька корисних лінків
Комментариев нет:
Отправить комментарий