Csharp/C Sharp/Language Basics/delegate Event — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Версия 18:31, 26 мая 2010
Содержание
- 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
<source lang="csharp"> /* 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(); }
}
</source>
An event multicast demonstration
<source lang="csharp"> /* 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(); }
}
</source>
A very simple event demonstration
<source lang="csharp"> /* 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(); }
}
</source>
Chaining events.
<source lang="csharp">
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); }
}
</source>
Create a custom means of managing the event invocation list
<source lang="csharp"> /* 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(); }
}
</source>
Delegate and event hierarchy
<source lang="csharp"> /*
* 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; } }
}
</source>
Delegates And Events
<source lang="csharp"> /* 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(); } } } </source>
Delegates And Events 2
<source lang="csharp"> /* 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(); } } } </source>
Events:Add and Remove Functions
<source lang="csharp"> 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(); }
}
</source>
Events:Add and Remove Functions 2
<source lang="csharp"> 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(); }
}
</source>
Events: Custom Add and Remove
<source lang="csharp"> /* 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(); }
}
</source>
Individual objects receive notifications when instance event handlers are used
<source lang="csharp"> /* 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(); }
}
</source>
Use delegate: event
<source lang="csharp"> /*
* 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; } }
}
</source>
Use the bult-in EventHandler delegate
<source lang="csharp"> /* 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(); }
}
</source>