Csharp/C Sharp/Language Basics/delegate Event
Содержание
- 1 A class receives the notification when a static method is used as an event handler
- 2 An event multicast demonstration
- 3 A very simple event demonstration
- 4 Chaining events.
- 5 Create a custom means of managing the event invocation list
- 6 Delegate and event hierarchy
- 7 Delegates And Events
- 8 Delegates And Events 2
- 9 Events:Add and Remove Functions
- 10 Events:Add and Remove Functions 2
- 11 Events: Custom Add and Remove
- 12 Individual objects receive notifications when instance event handlers are used
- 13 Use delegate: event
- 14 Use the bult-in EventHandler delegate
A class receives the notification when a static method is used as an event handler
/*
C#: The Complete Reference
by Herbert Schildt
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/
/* A class receives the notification when
a static method is used as an event handler. */
using System;
// Declare a delegate for an event.
delegate void MyEventHandler();
// Declare an event class.
class MyEvent {
public event MyEventHandler SomeEvent;
// This is called to fire the event.
public void OnSomeEvent() {
if(SomeEvent != null)
SomeEvent();
}
}
class X {
/* This is a static method that will be used as
an event handler. */
public static void Xhandler() {
Console.WriteLine("Event received by class.");
}
}
public class EventDemo3 {
public static void Main() {
MyEvent evt = new MyEvent();
evt.SomeEvent += new MyEventHandler(X.Xhandler);
// Fire the event.
evt.OnSomeEvent();
}
}
An event multicast demonstration
/*
C#: The Complete Reference
by Herbert Schildt
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/
// An event multicast demonstration.
using System;
// Declare a delegate for an event.
delegate void MyEventHandler();
// Declare an event class.
class MyEvent {
public event MyEventHandler SomeEvent;
// This is called to fire the event.
public void OnSomeEvent() {
if(SomeEvent != null)
SomeEvent();
}
}
class X {
public void Xhandler() {
Console.WriteLine("Event received by X object");
}
}
class Y {
public void Yhandler() {
Console.WriteLine("Event received by Y object");
}
}
public class EventDemo1 {
static void handler() {
Console.WriteLine("Event received by EventDemo");
}
public static void Main() {
MyEvent evt = new MyEvent();
X xOb = new X();
Y yOb = new Y();
// Add handlers to the event list.
evt.SomeEvent += new MyEventHandler(handler);
evt.SomeEvent += new MyEventHandler(xOb.Xhandler);
evt.SomeEvent += new MyEventHandler(yOb.Yhandler);
// Fire the event.
evt.OnSomeEvent();
Console.WriteLine();
// Remove a handler.
evt.SomeEvent -= new MyEventHandler(xOb.Xhandler);
evt.OnSomeEvent();
}
}
A very simple event demonstration
/*
C#: The Complete Reference
by Herbert Schildt
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/
// A very simple event demonstration.
using System;
// Declare a delegate for an event.
delegate void MyEventHandler();
// Declare an event class.
class MyEvent {
public event MyEventHandler SomeEvent;
// This is called to fire the event.
public void OnSomeEvent() {
if(SomeEvent != null)
SomeEvent();
}
}
public class EventDemo {
// An event handler.
static void handler() {
Console.WriteLine("Event occurred");
}
public static void Main() {
MyEvent evt = new MyEvent();
// Add handler() to the event list.
evt.SomeEvent += new MyEventHandler(handler);
// Fire the event.
evt.OnSomeEvent();
}
}
Chaining events.
using System;
public class EventTestClass {
private int nValue;
public delegate void ValueChangedEventHandler();
public event ValueChangedEventHandler Changed;
protected virtual void OnChanged() {
if (Changed != null)
Changed();
else
Console.WriteLine("Event fired. No handler!");
}
public EventTestClass(int nValue) {
SetValue(nValue);
}
public void SetValue(int nV) {
if (nValue != nV) {
nValue = nV;
OnChanged();
}
}
}
public class Mainclass {
public void HandleChange1() {
Console.WriteLine("Handler 1 Called");
}
public void HandleChange2() {
Console.WriteLine("Handler 2 Called");
}
public Mainclass() {
}
public static void Main() {
EventTestClass etc = new EventTestClass(3);
Mainclass app = new Mainclass();
etc.Changed += new EventTestClass.ValueChangedEventHandler(app.HandleChange1);
etc.Changed += new EventTestClass.ValueChangedEventHandler(app.HandleChange2);
etc.SetValue(5);
etc.SetValue(5);
etc.SetValue(3);
}
}
Create a custom means of managing the event invocation list
/*
C#: The Complete Reference
by Herbert Schildt
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/
// Create a custom means of managing the event invocation list.
using System;
// Declare a delegate for an event.
delegate void MyEventHandler();
// Declare an event class that holds up to 3 events.
class MyEvent {
MyEventHandler[] evnt = new MyEventHandler[3];
public event MyEventHandler SomeEvent {
// Add an event to the list.
add {
int i;
for(i=0; i < 3; i++)
if(evnt[i] == null) {
evnt[i] = value;
break;
}
if (i == 3) Console.WriteLine("Event list full.");
}
// Remove an event from the list.
remove {
int i;
for(i=0; i < 3; i++)
if(evnt[i] == value) {
evnt[i] = null;
break;
}
if (i == 3) Console.WriteLine("Event handler not found.");
}
}
// This is called to fire the events.
public void OnSomeEvent() {
for(int i=0; i < 3; i++)
if(evnt[i] != null) evnt[i]();
}
}
// Create some classes that use MyEventHandler.
class W {
public void Whandler() {
Console.WriteLine("Event received by W object");
}
}
class X {
public void Xhandler() {
Console.WriteLine("Event received by X object");
}
}
class Y {
public void Yhandler() {
Console.WriteLine("Event received by Y object");
}
}
class Z {
public void Zhandler() {
Console.WriteLine("Event received by Z object");
}
}
public class EventDemo4 {
public static void Main() {
MyEvent evt = new MyEvent();
W wOb = new W();
X xOb = new X();
Y yOb = new Y();
Z zOb = new Z();
// Add handlers to the event list.
Console.WriteLine("Adding events.");
evt.SomeEvent += new MyEventHandler(wOb.Whandler);
evt.SomeEvent += new MyEventHandler(xOb.Xhandler);
evt.SomeEvent += new MyEventHandler(yOb.Yhandler);
// Can"t store this one -- full.
evt.SomeEvent += new MyEventHandler(zOb.Zhandler);
Console.WriteLine();
// Fire the events.
evt.OnSomeEvent();
Console.WriteLine();
// Remove a handler.
Console.WriteLine("Remove xOb.Xhandler.");
evt.SomeEvent -= new MyEventHandler(xOb.Xhandler);
evt.OnSomeEvent();
Console.WriteLine();
// Try to remove it again.
Console.WriteLine("Try to remove xOb.Xhandler again.");
evt.SomeEvent -= new MyEventHandler(xOb.Xhandler);
evt.OnSomeEvent();
Console.WriteLine();
// Now, add Zhandler.
Console.WriteLine("Add zOb.Zhandler.");
evt.SomeEvent += new MyEventHandler(zOb.Zhandler);
evt.OnSomeEvent();
}
}
Delegate and event hierarchy
/*
* C# Programmers Pocket Consultant
* Author: Gregory S. MacBeth
* Email: gmacbeth@comporium.net
* Create Date: June 27, 2003
* Last Modified Date:
*/
using System;
namespace Client.Chapter_8___Delegates_and_Events
{
public delegate int MyDelegateEventHandler(MyEventArgs e);
public class MyEventSubscriber
{
static void Main(string[] args)
{
MyEventPublisher EventPublisher = new MyEventPublisher();
MyEventArgs MyArgs = new MyEventArgs();
MyArgs.MyString = "Hello World";
EventPublisher.MyEvent += new MyDelegateEventHandler(MyHandler);
EventPublisher.DoSomething(MyArgs);
}
static int MyHandler(MyEventArgs e)
{
Console.WriteLine(e.MyString);
return 0;
}
}
public class MyEventArgs: EventArgs
{
public int MyInt;
public long MyLong;
public string MyString;
}
public class MyEventPublisher
{
public event MyDelegateEventHandler MyEvent;
public int DoSomething(MyEventArgs e)
{
MyEvent(e);
return 0;
}
}
}
Delegates And Events
/*
Learning C#
by Jesse Liberty
Publisher: O"Reilly
ISBN: 0596003765
*/
using System;
namespace DelegatesAndEvents
{
public enum comparison
{
theFirstComesFirst = 1,
theSecondComesFirst = 2
}
// A simple collection to hold two items
class Pair
{
// Private array to hold the two objects
private object[] thePair = new object[2];
// The delegate declaration
public delegate comparison
WhichIsFirst(object obj1, object obj2);
// Passed in constructor takes two objects,
// added in order received
public Pair(
object firstObject,
object secondObject)
{
thePair[0] = firstObject;
thePair[1] = secondObject;
}
// Public method that orders the
// two objects by whatever criteria the objects like!
public void Sort(
WhichIsFirst theDelegatedFunc)
{
if (theDelegatedFunc(thePair[0],thePair[1])
== comparison.theSecondComesFirst)
{
object temp = thePair[0];
thePair[0] = thePair[1];
thePair[1] = temp;
}
}
// Public method that orders the
// two objects by the reverse of whatever criteria the
// objects likes!
public void ReverseSort(
WhichIsFirst theDelegatedFunc)
{
if (theDelegatedFunc(thePair[0],thePair[1]) ==
comparison.theFirstComesFirst)
{
object temp = thePair[0];
thePair[0] = thePair[1];
thePair[1] = temp;
}
}
// Ask the two objects to give their string value
public override string ToString()
{
return thePair[0].ToString() + ", "
+ thePair[1].ToString();
}
}
class Dog
{
private int weight;
public Dog(int weight)
{
this.weight=weight;
}
// dogs are sorted by weight
public static comparison WhichDogComesFirst(
Object o1, Object o2)
{
Dog d1 = (Dog) o1;
Dog d2 = (Dog) o2;
return d1.weight > d2.weight ?
comparison.theSecondComesFirst :
comparison.theFirstComesFirst;
}
public override string ToString()
{
return weight.ToString();
}
}
class Student
{
private string name;
public Student(string name)
{
this.name = name;
}
// Students are sorted alphabetically
public static comparison
WhichStudentComesFirst(Object o1, Object o2)
{
Student s1 = (Student) o1;
Student s2 = (Student) o2;
return (String.rupare(s1.name, s2.name) < 0 ?
comparison.theFirstComesFirst :
comparison.theSecondComesFirst);
}
public override string ToString()
{
return name;
}
}
public class TesterDelegatesAndEvents11
{
public void Run()
{
// Create two students and two dogs
// and add them to Pair objects
Student Jesse = new Student("Jesse");
Student Stacey = new Student ("Stacey");
Dog Milo = new Dog(65);
Dog Fred = new Dog(12);
Pair studentPair = new Pair(Jesse,Stacey);
Pair dogPair = new Pair(Milo, Fred);
Console.WriteLine("studentPair\t\t\t: {0}",
studentPair.ToString());
Console.WriteLine("dogPair\t\t\t\t: {0}",
dogPair.ToString());
// Instantiate the delegates
Pair.WhichIsFirst theStudentDelegate =
new Pair.WhichIsFirst(
Student.WhichStudentComesFirst);
Pair.WhichIsFirst theDogDelegate =
new Pair.WhichIsFirst(
Dog.WhichDogComesFirst);
// Sort using the delegates
studentPair.Sort(theStudentDelegate);
Console.WriteLine("After Sort studentPair\t\t: {0}",
studentPair.ToString());
studentPair.ReverseSort(theStudentDelegate);
Console.WriteLine("After ReverseSort studentPair\t: {0}",
studentPair.ToString());
dogPair.Sort(theDogDelegate);
Console.WriteLine("After Sort dogPair\t\t: {0}",
dogPair.ToString());
dogPair.ReverseSort(theDogDelegate);
Console.WriteLine("After ReverseSort dogPair\t: {0}",
dogPair.ToString());
}
static void Main()
{
TesterDelegatesAndEvents11 t = new TesterDelegatesAndEvents11();
t.Run();
}
}
}
Delegates And Events 2
/*
Learning C#
by Jesse Liberty
Publisher: O"Reilly
ISBN: 0596003765
*/
using System;
namespace DelegatesAndEvents
{
public enum comparison
{
theFirstComesFirst = 1,
theSecondComesFirst = 2
}
// A simple collection to hold two items.
class Pair
{
// Private array to hold the two objects.
private object[] thePair = new object[2];
// The delegate declaration.
public delegate comparison
WhichIsFirst(object obj1, object obj2);
// Passed in constructor takes two objects,
// added in order received.
public Pair(
object firstObject,
object secondObject)
{
thePair[0] = firstObject;
thePair[1] = secondObject;
}
// Public method that orders
// the two objects by whatever criteria the objects like!
public void Sort(
WhichIsFirst theDelegatedFunc)
{
if (theDelegatedFunc(thePair[0],thePair[1])
== comparison.theSecondComesFirst)
{
object temp = thePair[0];
thePair[0] = thePair[1];
thePair[1] = temp;
}
}
// Public method that orders
// the two objects by the reverse of whatever criteria
// the objects like!
public void ReverseSort(
WhichIsFirst theDelegatedFunc)
{
if (theDelegatedFunc(thePair[0],thePair[1]) ==
comparison.theFirstComesFirst)
{
object temp = thePair[0];
thePair[0] = thePair[1];
thePair[1] = temp;
}
}
// Ask the two objects to give their string value.
public override string ToString()
{
return thePair[0].ToString() + ", "
+ thePair[1].ToString();
}
}
class Dog
{
private int weight;
// A static delegate.
public static readonly Pair.WhichIsFirst OrderDogs =
new Pair.WhichIsFirst(Dog. WhichDogComesFirst);
public Dog(int weight)
{
this.weight=weight;
}
// Dogs are sorted by weight.
public static comparison WhichDogComesFirst(
Object o1, Object o2)
{
Dog d1 = (Dog) o1;
Dog d2 = (Dog) o2;
return d1.weight > d2.weight ?
comparison.theSecondComesFirst :
comparison.theFirstComesFirst;
}
public override string ToString()
{
return weight.ToString();
}
}
class Student
{
private string name;
// A static delegate.
public static readonly Pair.WhichIsFirst OrderStudents =
new Pair.WhichIsFirst(Student.WhichStudentComesFirst);
public Student(string name)
{
this.name = name;
}
// Students are sorted alphabetically.
public static comparison
WhichStudentComesFirst(Object o1, Object o2)
{
Student s1 = (Student) o1;
Student s2 = (Student) o2;
return (String.rupare(s1.name, s2.name) < 0 ?
comparison.theFirstComesFirst :
comparison.theSecondComesFirst);
}
public override string ToString()
{
return name;
}
}
public class TesterDelegatesAndEvents1
{
public void Run()
{
// Create two students and two dogs
// and add them to Pair objects.
Student Jesse = new Student("Jesse");
Student Stacey = new Student ("Stacey");
Dog Milo = new Dog(65);
Dog Fred = new Dog(12);
// Create the Pair object.
Pair studentPair = new Pair(Jesse,Stacey);
Pair dogPair = new Pair(Milo, Fred);
Console.WriteLine("studentPair\t\t\t: {0}",
studentPair.ToString());
Console.WriteLine("dogPair\t\t\t\t: {0}",
dogPair.ToString());
// Tell the student Pair to sort itself,
// passing in the Student delegate.
studentPair.Sort(Student.OrderStudents);
Console.WriteLine("After Sort studentPair\t\t: {0}",
studentPair.ToString());
studentPair.ReverseSort(Student.OrderStudents);
Console.WriteLine("After ReverseSort studentPair\t: {0}",
studentPair.ToString());
// Tell the Dog pair to sort itself,
// passing in the Dog delegate.
dogPair.Sort(Dog.OrderDogs);
Console.WriteLine("After Sort dogPair\t\t: {0}",
dogPair.ToString());
dogPair.ReverseSort(Dog.OrderDogs);
Console.WriteLine("After ReverseSort dogPair\t: {0}",
dogPair.ToString());
}
[STAThread]
static void Main()
{
TesterDelegatesAndEvents1 t = new TesterDelegatesAndEvents1();
t.Run();
}
}
}
Events:Add and Remove Functions
using System;
public class AddandRemoveFunctions {
static public void ButtonHandler(object sender, EventArgs e)
{
Console.WriteLine("Button clicked");
}
public static void Main()
{
Button button = new Button();
button.AddClick(new Button.ClickHandler(ButtonHandler));
button.SimulateClick();
button.RemoveClick(new Button.ClickHandler(ButtonHandler));
}
}
public class Button
{
public delegate void ClickHandler(object sender, EventArgs e);
private ClickHandler click;
public void AddClick(ClickHandler clickHandler)
{
click += clickHandler;
}
public void RemoveClick(ClickHandler clickHandler)
{
click -= clickHandler;
}
protected void OnClick()
{
if (click != null)
click(this, null);
}
public void SimulateClick()
{
OnClick();
}
}
Events:Add and Remove Functions 2
using System;
public class AddandRemoveFunctions2
{
static public void ButtonHandler(object sender, EventArgs e)
{
Console.WriteLine("Button clicked");
}
public static void Main()
{
Button button = new Button();
button.Click += new Button.ClickHandler(ButtonHandler);
button.SimulateClick();
button.Click -= new Button.ClickHandler(ButtonHandler);
}
}
public class Button
{
public delegate void ClickHandler(object sender, EventArgs e);
public event ClickHandler Click;
protected void OnClick()
{
if (Click != null)
Click(this, null);
}
public void SimulateClick()
{
OnClick();
}
}
Events: Custom Add and Remove
/*
A Programmer"s Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress L.P.
ISBN: 1-893115-62-3
*/
// 23 - Events\Custom Add and Remove
// copyright 2000 Eric Gunnerson
using System;
using System.Collections;
using System.Runtime.rupilerServices;
public class EventsCustomAddandRemove
{
static public void ButtonHandler(object sender, EventArgs e)
{
Console.WriteLine("Button clicked");
}
public static void Main()
{
Button button = new Button();
button.Click += new Button.ClickHandler(ButtonHandler);
button.SimulateClick();
button.Click -= new Button.ClickHandler(ButtonHandler);
button.TearDown();
}
}
//
// Global delegate cache. Uses a two-level hashtable. The delegateStore hashtable
// stores a hashtable keyed on the object instance, and the instance hashtable is
// keyed on the unique key. This allows fast tear-down of the object when it"s destroyed.
//
public class DelegateCache
{
private DelegateCache() {} // nobody can create one of these
Hashtable delegateStore = new Hashtable(); // top level hash table
static DelegateCache dc = new DelegateCache(); // our single instance
Hashtable GetInstanceHash(object instance)
{
Hashtable instanceHash = (Hashtable) delegateStore[instance];
if (instanceHash == null)
{
instanceHash = new Hashtable();
delegateStore[instance] = instanceHash;
}
return(instanceHash);
}
public static void Combine(Delegate myDelegate, object instance, object key)
{
lock(instance)
{
Hashtable instanceHash = dc.GetInstanceHash(instance);
instanceHash[key] = Delegate.rubine((Delegate) instanceHash[key],
myDelegate);
}
}
public static void Remove(Delegate myDelegate, object instance, object key)
{
lock(instance)
{
Hashtable instanceHash = dc.GetInstanceHash(instance);
instanceHash[key] = Delegate.Remove((Delegate) instanceHash[key],
myDelegate);
}
}
public static Delegate Fetch(object instance, object key)
{
Hashtable instanceHash = dc.GetInstanceHash(instance);
return((Delegate) instanceHash[key]);
}
public static void ClearDelegates(object instance)
{
dc.delegateStore.Remove(instance);
}
}
public class Button
{
public void TearDown()
{
DelegateCache.ClearDelegates(this);
}
public delegate void ClickHandler(object sender, EventArgs e);
static object clickEventKey = new object();
public event ClickHandler Click
{
add
{
DelegateCache.rubine(value, this, clickEventKey);
}
remove
{
DelegateCache.Remove(value, this, clickEventKey);
}
}
protected void OnClick()
{
ClickHandler ch = (ClickHandler) DelegateCache.Fetch(this, clickEventKey);
if (ch != null)
ch(this, null);
}
public void SimulateClick()
{
OnClick();
}
}
Individual objects receive notifications when instance event handlers are used
/*
C#: The Complete Reference
by Herbert Schildt
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/
/* Individual objects receive notifications when instance
event handlers are used. */
using System;
// Declare a delegate for an event.
delegate void MyEventHandler();
// Declare an event class.
class MyEvent {
public event MyEventHandler SomeEvent;
// This is called to fire the event.
public void OnSomeEvent() {
if(SomeEvent != null)
SomeEvent();
}
}
class X {
int id;
public X(int x) { id = x; }
// This is an instance method that will be used as an event handler.
public void Xhandler() {
Console.WriteLine("Event received by object " + id);
}
}
public class EventDemo2 {
public static void Main() {
MyEvent evt = new MyEvent();
X o1 = new X(1);
X o2 = new X(2);
X o3 = new X(3);
evt.SomeEvent += new MyEventHandler(o1.Xhandler);
evt.SomeEvent += new MyEventHandler(o2.Xhandler);
evt.SomeEvent += new MyEventHandler(o3.Xhandler);
// Fire the event.
evt.OnSomeEvent();
}
}
Use delegate: event
/*
* C# Programmers Pocket Consultant
* Author: Gregory S. MacBeth
* Email: gmacbeth@comporium.net
* Create Date: June 27, 2003
* Last Modified Date:
*/
using System;
namespace Client.Chapter_8___Delegates_and_Events
{
public delegate void MyDelegateEventHandler(int i);
public class MyEventSubscriberChapter_8___Delegates_and_Events
{
static void Main(string[] args)
{
MyEventPublisher EventPublisher = new MyEventPublisher();
MyDelegateEventHandler MyAnonymousDelegate = delegate(int x)
{
Console.WriteLine("Anonymous Event FIRED!");
};
EventPublisher.MyEvent += MyAnonymousDelegate;
EventPublisher.DoSomething();
}
}
public class MyEventPublisher
{
public event MyDelegateEventHandler MyEvent;
public int DoSomething()
{
MyEvent(5);
return 0;
}
}
}
Use the bult-in EventHandler delegate
/*
C#: The Complete Reference
by Herbert Schildt
Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/
// Use the bult-in EventHandler delegate.
using System;
// Declare an event class.
class MyEvent {
public event EventHandler SomeEvent; // uses EventHandler delegate
// This is called to fire SomeEvent.
public void OnSomeEvent() {
if(SomeEvent != null)
SomeEvent(this, EventArgs.Empty);
}
}
public class EventDemo6 {
static void handler(object source, EventArgs arg) {
Console.WriteLine("Event occurred");
Console.WriteLine("Source is " + source);
}
public static void Main() {
MyEvent evt = new MyEvent();
// Add handler() to the event list.
evt.SomeEvent += new EventHandler(handler);
// Fire the event.
evt.OnSomeEvent();
}
}