[C # Basic Knowledge series] Theme 11: anonymous method analysis

Source: Internet
Author: User
Tags event timer

Introduction:

I feel like I haven't updated my blog for a long time. The anonymous method will be introduced in this topic. The anonymous method can also be understood by name, of courseMethod without name(In real life, there are also many such anonymous processes, such as anonymous voting and anonymous reporting. I believe Microsoft will certainly follow the examples in life in terms of naming ), however, the understanding of the anonymous method is not just this sentence (this sentence refers to the method without a name). It also has a lot of content. Next we will introduce the specific content of the anonymous method.

 

1. Anonymous Method

I used to think that the anonymous method was proposed in C #3.0. The reason for this was that C #3.0 proposed the anonymous type, therefore, it is taken for granted that the anonymous method was proposed in C #3.0, however, after systematically learning the C # feature, we found that the anonymous method was proposed at C #2.0. From the perspective of the feature development, we can see that Microsoft's team is very well planned, in fact, the subsequent features have been planned before, and the subsequent features have evolved from previous features. The reason why new features are proposed is mainly to facilitate programming, reduce the programmer's work, allow the compiler to execute more complex operations, and enable the programmer to focus on implementing the business logic methods of his system (this is also the main idea of Microsoft, it is also a good user experience that most software emphasizes.The anonymous method is based on the delegation in C #1.0.(At the same time, C #2.0 has enhanced the delegation, and proposed generic delegation, as well as the co-variant and inverter of the delegated parameters. For details, refer to the previous topics in this series ), next I will explain in detail how the anonymous method is based on the delegate (the delegate is the method packaging, and the anonymous method is also the method, but the anonymous method has no name, therefore, the delegate can also wrap the anonymous method ).

First, we will introduce the concept of anonymous methods, namely anonymous methods-methods without names (methods are also the concepts of functions in mathematics ), the anonymous method only does not specify a name in the source code. In fact, the compiler will generate a name for the anonymous method. However, it is because there is no name in the source code, therefore, an anonymous method can only be called when defined, and cannot be called elsewhere (an anonymous method embeds the definition of a method and implementation of a method ), the following example shows how to associate the anonymous method with the delegate:

Namespace anonymous method demo {class program {// defines the vote delegate void votedelegate (string name); static void main (string [] ARGs) {// instantiate the delegate object votedelegate = new votedelegate (new friend (). vote); // code using the anonymous method // The anonymous method is inline with a delegate instance (which can be understood by the code of the preceding delegate instantiation) // after using the anonymous method, we don't need to define a friend class and define a voting method separately. // This can reduce the amount of code and reduce the amount of code, which is much easier to read, so that the definition of too many callback methods will not be confused. // votedelegate = delegate (string nickname) // {// console. writeline ("nickname: {0} To help learning hard vote", nickname); //}; // call the back and forth vote () method votedelegate ("somebody"); console. read () ;}} public class friend {// friend's voting method public void vote (string nickname) {console. writeline ("nickname: {0} helped learning hard vote", nickname );}}}

I participated in the 51 blog contest some time ago and pulled a lot of friends to vote in the voting stage. So I want to thank them, so I used the voting as an example to illustrate the anonymous method, the comments have explained the benefits of the anonymous method, which can help us reduce the amount of writing code and facilitate reading. However, what can I do to replace the delegate with the anonymous method above? Do we need to replace all the places where delegation is used with the anonymous method? This is not the case because the anonymous method has no name, so it cannot be called elsewhere.ReuseAnd the anonymous method automatically forms the "closure" (if you do not understand the closure of friends can refer to these two links: http://baike.baidu.com/view/648413.htm and http://zh.wikipedia.org/wiki/closed package _ (computer science ), what I understand is that when a function (external function) calls another function (called an internal function) and an internal function uses a variable in an external function, in this way, a closure may be formed. For specific concepts, refer to the above two links. Examples of closures will be provided in the following sections to help you understand them. Since anonymous functions form closures, this will prolong the life cycle of the variable ).Therefore, if the delegate packaging method is relatively simple (just like the preceding Code only outputs a single line of statements), and this method is used very frequently elsewhere, in this case, you can use the anonymous method instead of the delegate..

Ii. using anonymous methods to ignore delegate Parameters

The first part mainly introduces the concept of the anonymous method, and introduces why the anonymous method is proposed. (to facilitate the instantiation of the delegated instance, you can use the anonymous method to inline delegate the instance, in this way, avoid defining an additional instance method, reduce the amount of code, and facilitate reading). In this section, we will introduce another benefit of the anonymous method-ignore the delegate parameter. The following is an example of code to help you understand the Code. The Code contains detailed comments, so we will not talk about it here. Let's look at the Code directly:

Namespace ignores the delegate parameter demo {class program {static void main (string [] ARGs) {// The Timer class generates a scheduled event system in the application. timers. timer timer = new system. timers. timer (); // indicates whether the elapsed Event timer is triggered. enabled = true; // sets the interval timer for triggering elapsed events. interval = 1000; // when the elapsed event reaches the interval, the previous time interval is set to 1 second. // Therefore, The elapsed event is triggered every second and the timer_elapsed method is called back, output Current Time // timer. elapsed + = new system. timers. elapsedeventhandler (timer_elapsed); // at this time, the parameters in the timer_elapsed method are not required at all. Therefore, we can use the anonymous method to omit the delegate parameter. // After the parameter is omitted, our code is more concise, it looks so comfortable. // we often do not use the delegate parameter in winform development. In this case, we can use the anonymous method to omit the parameter timer. elapsed + = delegate {console. writeline (datetime. now) ;}; console. read ();} public static void timer_elapsed (Object sender, system. timers. elapsedeventargs e) {console. writeline (datetime. now );}}}

The running result is:

The code above uses the anonymous method to omit the delegate parameter. However, for the compiler, it still calls the Delegate constructor to instantiate the delegate. Therefore, if the anonymous method can be converted to multiple Delegate types, if the delegate parameter is omitted, the compiler does not know the specific delegate type to which the anonymous method is converted. Therefore, a compile-time error occurs, in this case, you must manually specify parameters to tell the compiler how to instantiate the delegate, the following uses the thread creation as an example to help you understand the problem caused by omitting the delegate parameter in an anonymous method (because the thread creation involves two Delegate types: Public Delegate void threadstart () and public delegaye void parameterizedthreadstart (objec OBJ )):

Class program {static void main (string [] ARGs) {New thread (delegate () {console. writeline ("thread 1") ;}); new thread (delegate (Object O) {console. writeline ("thread 2") ;}); new thread (delegate {console. writeline ("thread 3") ;}); console. read ();}}

At this time, the code of the third creation thread will see the following compilation error:

3. Capture variables in anonymous methods

As mentioned in the previous section, a closure is formed when an anonymous method is used. A closure refers to capturing variables in an anonymous method. To better understand the concept of a closure, you must first understand the two concepts --External variablesAndCaptured external variablesHere is an example to explain the two concepts:

Class program {// define the closure delegate void closuredelegate (); static void main (string [] ARGs) {closuremethod (); console. read () ;}// closure method Private Static void closuremethod () {// outvariable and capturedvariable are both external variables for anonymous methods // However, outvariable is an uncaptured external variable, the sub-object is not captured because the string outvariable = "external variable" is not referenced in the anonymous method "; // capturedvariable is the external variable string capturedvariable = "Capture variable" captured by the anonymous method "; closuredelegate = delegate {// localvariable is the local variable string localvariable = "anonymous method local variable"; console. writeline (capturedvariable + "" + localvariable) ;}; // call the delegate closuredelegate ();}}

After a variable is captured, what is captured by the anonymous method is true.Variable, AndNoThe variableValue,And the variable captured by the anonymous method will prolong the life cycle (that is, for a captured variable, it will always exist as long as any delegate instance references it, instead of being reclaimed after the delegate instance is called). The following uses a specific example to see how the anonymous method prolongs the life cycle of a variable:

Class program {// defines the closure delegate void closuredelegate (); static void main (string [] ARGs) {closuredelegate test = createdelegateinstance (); test (); console. read () ;}// closure extends the life cycle of the variable Private Static closuredelegate createdelegateinstance () {int COUNT = 1; closuredelegate = delegate {console. writeline (count); count ++;}; // call the delegate closuredelegate (); Return closuredelegate ;}}

The running result is:

1 In the first row is the result of calling the delegate instance internally by createdelegateinstance. First, you must consider that count is allocated on the stack (because count is a value type ), after the createdelegateinstance method is called, the Count value is destroyed. When the code test () is executed, the anonymous method is called back to output the Count value because the Count value is destroyed, it is true that there should be exceptions, but the result is 2. However, there is nothing wrong with the result. If we push the result backwards, we can conclude that, the second call to the delegated instance is still using the original count. However, we think that an exception is thrown mainly because we think that count is allocated on the stack, however, this is not the case. The Count variable is not allocated to the stack,In fact, the compiler will create an additional class to hold the variable (in this case, the Count variable is allocated on the heap). The createdelegateinstance method has reference to an instance of this class, therefore, the Count variable captured by the anonymous method is a reference of the variable instead of a real value. At the same time, the anonymous method extends the life cycle of the variable count, it does not feel like a local variable, but a "global variable" (because the delegate instance called in the second time uses the same count ).

The compiler will create an additional class to accommodate the variable captured by the anonymous method. For this, you can view it through the Il disassembly program, the following is obtained by using the disassembly program in the above program:

 

From the above, we can see that there is no<> C_displayclass1Class definition, however, this class is really created by the compiler for us to accommodate the capture variable count, and this class contains the createdelegateinstance method. From the left half of the intermediate language code, we can see that, the createdelegateinstance method defined in the source code has<> A reference of c_displayclass1,The Count variable compiler used in source code considers it to be<> C_displayclass1A field.

Iv. Summary

This topic describes how to use anonymous methods and how to capture variables to prolong the life cycle of variables, I hope you can have a comprehensive understanding of the anonymous method through the introduction of this topic, and the anonymous method is also the basis of lambda expressions, lambda expressions are just a more concise method proposed in C #3.0 to implement anonymous methods.

 

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.