Delegates
A delegate is a reference type, but instead of referring to an object, a delegate refers to a method. In other words, a delegate is a type that represents references to methods with a particular parameter list and return type. This is called encapsulating the method. When you create the delegate, you specify a method signature and return type; you can encapsulate any matching method with that delegate. It is like a function pointer in C++ but are type safe (the method passed needs to conform to the method signature).
You create a delegate with the delegate keyword, followed by a return type and the signature of the methods that can be delegated to it, as in the following:
public delegate int FindResult(object obj1, object obj2);
class MediaStorage {
public delegate int PlayMedia();
public void ReportResult(PlayMedia playerDelegate) { if (playerDelegate( ) == 0) { Console.WriteLine("Media played successfully."); } else { Console.WriteLine("Media did not play successfully."); } }
}
public class AudioPlayer { private int audioPlayerStatus; public int PlayAudioFile( ) { Console.WriteLine("Simulating playing an audio file here."); audioPlayerStatus = 0; return audioPlayerStatus; } }
MediaStorage myMediaStorage = new MediaStorage( );
// instantiate the delegates
// PlayAudioFile conforms to the PlayMedia delegate signature MediaStorage.PlayMedia audioPlayerDelegate = new MediaStorage.PlayMedia(myAudioPlayer.PlayAudioFile);
myMediaStorage.ReportResult(audioPlayerDelegate);
Events and Delegates
class Clock {
// Define the SecondChangedHandler delegate type. This delegate will encapsulate any method that// returns void and that takes two parameters.public delegate void SecondChangeHandler( object clock, TimeInfoEventArgs timeInformation);// Create an instance of the delegate public SecondChangeHandler SecondChanged;}class DisplayClock {public void Subscribe(Clock theClock) { theClock.SecondChanged += new Clock.SecondChangeHandler(WriteLogEntry); }
}The problem with the above code snippet is that other methods can call SecondChanged directly and this is not normally the original class intends.. For example:Console.WriteLine("Calling the method directly!"); System.DateTime dt = System.DateTime.Now.AddHours(2); TimeInfoEventArgs timeInformation = new TimeInfoEventArgs( dt.Hour,dt.Minute,dt.Second); theClock.SecondChanged(theClock, timeInformation);
To prevent external calls to the delegated method directly, one can make the delegate private, but then this will prevent clients from registering with the delegate at all. What's needed is a way to say, "This delegate is designed for event handling: you may subscribe and unsubscribe, but you may not invoke it directly."
Reference:
To fix your program, change your definition of SecondChanged from:
public SecondChangeHandler SecondChanged;
to the following:
public event SecondChangeHandler SecondChanged;
Adding the event keyword fixes both problems. Classes can no longer attempt to subscribe to the event using the assignment operator (=), as they could previously, nor can they invoke the event directly, as was done in the preceding example. Either of these attempts will now generate a compile error.
There are two ways of looking at SecondChanged now that you've modified it. In one sense, it is simply a delegate instance to which you've restricted access using the keyword event. In another, more important sense,SecondChanged is an event, implemented by a delegate of type SecondChangeHandler. These two statements mean the same thing, but the latter is a more object-oriented way of looking at it, and better reflects the intent of this keyword: to create an event that your object can raise, and to which other objects can respond.
There are two ways of looking at SecondChanged now that you've modified it. In one sense, it is simply a delegate instance to which you've restricted access using the keyword event. In another, more important sense,SecondChanged is an event, implemented by a delegate of type SecondChangeHandler. These two statements mean the same thing, but the latter is a more object-oriented way of looking at it, and better reflects the intent of this keyword: to create an event that your object can raise, and to which other objects can respond.
You can also assign this delegate by writing the shortened version:
theClock.SecondChanged += TimeHasChanged;
http://msdn.microsoft.com/en-us/library/orm-9780596521066-01-17.aspx
http://msdn.microsoft.com/en-us/library/ms173171.aspx
No comments :
Post a Comment