In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article shares with you the content of sample analysis of events and delegation mechanisms in C # development. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.
Overview
A delegate in C # is similar to a function pointer in C or C++. Using delegates enables programmers to encapsulate method references in delegate objects. You can then pass the delegate object to code that can call the referenced method without having to know which method will be called at compile time. Unlike function pointers in C or C++, delegates are object-oriented and type-safe.
The "event" in C # is a way for a class to notify customers of that class when something happens to the object. The most common use of events is for a graphical user interface; typically, classes that represent controls in the interface have events that are notified when the user performs certain actions on the control, such as clicking a button.
Use delegates to declare events. The delegate object encapsulates a method so that it can be called anonymously. An event is a method that a class allows a client to provide a delegate of methods that should be called when the event occurs. When the event occurs, the delegate provided to it by its customer is invoked.
Note: delegate is the wrapper of a method to use a delegate when you are not sure what method to call and cannot be implemented in abstraction or polymorphism.
Public interface PilotLamp {/ green light / void TurnOn (); / notice / string Notice {get; set;}}
Create a PilotLamp.cs first
Create the DelegateEvent.cs again:
Public delegate void EventHandler ()
Create the TrafficLight.cs again:
Public class TrafficLight: PilotLamp {public event EventHandler Notices; private string notice; # region GreenLight member public void TurnOn () {if (Notices! = null) Notices ();} public string Notice {get {return notice;} set {notice = value;} # endregion}
Create a Driver.cs again
Public class Driver private string Name; private PilotLamp greenLight; public Driver (string name, PilotLamp greenLight) {this.Name = name; this.greenLight = greenLight;} public void GoLeft () {Console.WriteLine (string.Format ("{1} driver, {0}, please drive left.", greenLight.Notice, Name);}}
Create the Pedestrian.cs again:
Public class Pedestrian {private string Name; private PilotLamp greenLight; public Pedestrian (string name, PilotLamp greenLight) {this.Name = name; this.greenLight = greenLight;} public void GoThrough () {Console.WriteLine ("{0} Comrade, {1}, please move forward.", Name, greenLight.Notice);}}
* call:
Public partial class Run: Form {public Run () {InitializeComponent ();} private void btnRun_Click (object sender, EventArgs e) {/ /-- TrafficLight trafficLight = new TrafficLight (); Driver driverOne = new Driver ("Zhang San", trafficLight); Driver driverTwo = new Driver ("Li Si", trafficLight) Pedestrian pedestrianOne = new Pedestrian ("Wang Wu", trafficLight); Pedestrian pedestrianTwo = new Pedestrian ("Malu", trafficLight); trafficLight.Notices + = new Observer.EventHandler (driverOne.GoLeft); trafficLight.Notices + = new Observer.EventHandler (driverTwo.GoLeft); trafficLight.Notices + = new Observer.EventHandler (pedestrianOne.GoThrough); trafficLight.Notices + = new Observer.EventHandler (pedestrianTwo.GoThrough); trafficLight.Notice = "Green light is on."; trafficLight.TurnOn () / /--}}
Select the console application when output as shown in the figure:
The result is as follows:
Examples of the use of events:
Namespace DelegateAndEvent {class Program {static void Main (string [] args) {Publishser pub = new Publishser (); OneScriber oneSub = new OneScriber (); TwoScriber twoSub = new TwoScriber (); ThreeScriber threeSub = new ThreeScriber (); pub.NumberChanged + = new GeneralEventHandler (oneSub.OnNumberChanged); pub.NumberChanged + = new GeneralEventHandler (twoSub.OnNumberChanged); pub.NumberChanged + = new GeneralEventHandler (threeSub.OnNumberChanged); pub.DoSomething ();}} public delegate string GeneralEventHandler () Public class Publishser {public event GeneralEventHandler NumberChanged; public void DoSomething () {if (NumberChanged! = null) {Delegate [] generalEventHandlers = NumberChanged.GetInvocationList (); foreach (Delegate generalEventHandler in generalEventHandlers) {GeneralEventHandler mothed = (GeneralEventHandler) generalEventHandler; string rtn = mothed (); Console.WriteLine (rtn); System.Threading.Thread.Sleep (2000) } public class OneScriber {public string OnNumberChanged () {return "One Subscriber";}} public class TwoScriber {public string OnNumberChanged () {return "Two Subscriber";}} public class ThreeScriber {public string OnNumberChanged () {return "Three Subscriber";}
Running result:
Notice that Delegate is the base class of GeneralEventHandler, so in order to trigger an event, you need to do a downward cast before you can trigger the event and call all methods that register the object. In addition to using this method, there is a more flexible way to call a method, which is the DynamicInvoke () method defined in the Delegate base class:
Public object DynamicInvoke (params object [] args)
This is probably the most common way to invoke a delegate and applies to all types of delegates. It accepts a parameter of object [], which means it can take any number of types as parameters and return a single object object. The above DoSomething () method can also be rewritten in the following general form:
Make the following changes to the code:
Namespace DelegateAndEvent {class Program {static void Main (string [] args) {Publishser pub = new Publishser (); OneScriber oneSub = new OneScriber (); TwoScriber twoSub = new TwoScriber (); ThreeScriber threeSub = new ThreeScriber (); pub.NumberChanged + = new GeneralEventHandler (oneSub.OnNumberChanged); pub.NumberChanged + = new GeneralEventHandler (twoSub.OnNumberChanged); pub.NumberChanged + = new GeneralEventHandler (threeSub.OnNumberChanged); List strlist = pub.DoSomething () Foreach (string result in strlist) Console.WriteLine (result); System.Threading.Thread.Sleep (5000);}} public delegate string GeneralEventHandler (); public class Publishser {public event GeneralEventHandler NumberChanged; public List DoSomething () {List strList = new List (); if (NumberChanged = = null) return strList; Delegate [] generalEventHandlers = NumberChanged.GetInvocationList () Foreach (Delegate generalEventHandler in generalEventHandlers) {/ / GeneralEventHandler mothed = (GeneralEventHandler) generalEventHandler; string rtn = generalEventHandler.DynamicInvoke (null). ToString (); strList.Add (rtn);} return strList;}} public class OneScriber {public string OnNumberChanged () {return "One Subscriber";}} public class TwoScriber {public string OnNumberChanged () {return "Two Subscriber" }} public class ThreeScriber {public string OnNumberChanged () {return "Three Subscriber";}
The results are as follows:
The result is the same.
The definition of the delegate generates a complete class that inherits from MulticastDelegate, including the Invoke (), BeginInvoke (), and EndInvoke () methods. When we call the delegate directly, we actually call the Invoke () method, which interrupts the client that called it, then executes all subscriber's methods on the client thread (the client cannot continue to execute the later code), and * returns control to the client. Notice that the BeginInvoke () and EndInvoke () methods are usually paired in .net, starting with Begin and End (probably the most common are the BeginRead () and EndRead () methods of the Stream class). They are used for asynchronous execution of methods, that is, after calling BeginInvoke (), the client grabs an idle thread from the thread pool and leaves it to execute the subscriber's method, while the client thread can continue to execute the following code.
BeginInvoke () accepts the number and type of parameters that are "dynamic". Why do you say "dynamic"? Because its parameters are dynamically generated according to the definition of the delegate at compile time, the number and type of the previous parameters are the same as those accepted in the delegate definition. The two parameters are AsyncCallback and Object respectively. For more details, please see the async invocation section of delegate and method in the next section. For now, we just need to pass in null for these two parameters. There are also a few points to pay attention to:
When BeginInvoke () is called on a delegate type, this delegate object can contain only one target method, so in the case of multiple subscribers registering, you must use GetInvocationList () to get all delegate objects, and then iterate through them, calling the BeginInvoke () method on them respectively. If BeginInvoke () is called directly on the delegate, an exception is thrown, indicating that "the delegate can only contain one target method."
If the subscriber's method throws an exception, .NET catches it, but only when EndInvoke () is called will the exception be rethrown. In this case, we do not use EndInvoke () (because we do not care about the execution of the subscriber), so we do not need to handle exceptions, because even if an exception is thrown, it is on another thread and does not affect the client thread (the client does not even know that the subscriber has an exception, which is sometimes a good thing and sometimes a bad thing)
The BeginInvoke () method belongs to the class generated by the delegate definition, and it belongs to neither the MulticastDelegate nor the Delegate base class. We need to do a downward transformation to get the actual delegate type.
Example:
Namespace DelegateAndEvent {class Program {static void Main (string [] args) {Publishser pub = new Publishser (); OneScriber oneSub = new OneScriber (); TwoScriber twoSub = new TwoScriber (); ThreeScriber threeSub = new ThreeScriber (); pub.NumberChanged + = new GeneralEventHandler (oneSub.OnNumberChanged); pub.NumberChanged + = new GeneralEventHandler (twoSub.OnNumberChanged); pub.NumberChanged + = new GeneralEventHandler (threeSub.OnNumberChanged); List strlist = pub.DoSomething () Foreach (string result in strlist) Console.WriteLine (result); System.Threading.Thread.Sleep (5000);} public delegate string GeneralEventHandler (object sender,EventArgs e); public class Publishser {public event GeneralEventHandler NumberChanged; public List DoSomething () {List strList = new List (); if (NumberChanged = = null) return strList; Delegate [] generalEventHandlers = NumberChanged.GetInvocationList () Foreach (Delegate generalEventHandler in generalEventHandlers) {GeneralEventHandler mothed = (GeneralEventHandler) generalEventHandler; IAsyncResult result = mothed.BeginInvoke (this, EventArgs.Empty, null, null); string str = mothed.EndInvoke (result); strList.Add (str);} return strList;}} public class OneScriber {public string OnNumberChanged (object sender,EventArgs e) {return "One Subscriber" }} public class TwoScriber {public string OnNumberChanged (object sender, EventArgs e) {return "Two Subscriber";}} public class ThreeScriber {public string OnNumberChanged (object sender, EventArgs e) {return "Three Subscriber";}
Results:
The other two parameters to BeginInvoke are AsyncCallback and Object, where AsyncCallback is a delegate type that is used for callbacks to methods, that is, methods that are called automatically when an asynchronous method finishes execution. It is defined as:
Public delegate void AsyncCallback (IAsyncResult ar)
The Object type is used to pass any value you want, which can be obtained through the AsyncState property of IAsyncResult.
Thank you for reading! This is the end of this article on "sample Analysis of events and delegation Mechanism in C# Development". I hope the above content can be helpful to you, so that you can learn more knowledge. If you think the article is good, you can share it for more people to see!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.