21 Anonymous Method 21.1. Anonymous Method Expression Anonymous Method Expression Defines an Anonymous Method, which will calculate a specific value to reference the method. l Primary-no-array-credibility-expression (basic non-array creation expression:) ... anonymous-method-expression (anonymous method expression)
l Anonymous-method-expression: delegate anonymous-method-signature opt block (anonymous method expression: DELEGATE anonymous method Sign option)
l Anonymous-method-signature: (anonymous-method-parameter-list) (anonymous method signature: anonymous method parameter list optional)
l Anonymous-method-parameter-list: anonymous-method-parameteranonymous-method-parameter-list, anonymous-method-parameter (anonymous method parameter list: anonymous method parameter anonymous method parameter list)
l anonymous-method-parameter: parameter-modifieropt type Identifier (anonymous method parameters: parameter modifier optional type identifier)
The anonymous method expression is classified as a value having a specific conversion rule (§21.3). The anonymous method expression defines a new declaration space for parameters, local variables, and constants, and defines a new declaration space for the label (3.3).
21.2 Anonymous Method Signature Optional Anonymous-Method-Signature Defines the name and type of the official parameters for the anonymous method. The parameter scope of an anonymous method is block (block). Match its scope contains local variables of anonymous-method-expression, local constant or parameters, and a compile time error for the name of anonymous method parameters. If an anonymous method expression has an anonymous method, then the compatible commission type will be restricted to those sets of commission types with the same order (21.3) the same parameter type and modifier. If an anonymous method expression does not have an anonymous method, then the compatible delegate type will be restricted to a set of delegate types without output parameters.
Note that an anonymous method signing cannot contain features or arguments arrays. However, anonymous method signatures can contain the parameter list compatible with the parameter group. 21.3 Anonymous Method Conversion Anonymous Method Expression is classified as a non-type value. An anonymous method expressions can be used to delegate create an expression (§ 21.3.1). All other legal use of an anonymous method expressions depends on implicit conversions defined here. Implicit conversions have an anonymous method expressions from any delegate compatible. If D is a delegation type, and A is an anonymous method expression, then if the following conditions are met, D is compatible with a compatibility: l First, D's parameter type and a compatibility: n If A does not include an anonymous method signature, Then D can have zero or multiple arbitrary parameters, provided that D does not have any parameters having an output parameter modifier. n If A has an anonymous method signature, then D must have the same number of parameters, and each parameter of A and D must have the same type, and the REF or OUT modifier of each parameter on A. No, you must match the corresponding parameters of D. The last parameter of D is whether the parameter arrays and D are independent of the compatibility of A. L Second, the return type of D must be compatible with A, for these rules, regardless of A containing any other anonymous method blocks. n If D is declared using a VOID declaration return type, then any return statement contained in A should not specify an expression. n If the D uses type R declaration returns, then any return statements containing in A must specify an expression that can be implicitly converted (§6.1) to R. Further, the end point of the block of A must be unreachable. In addition to any implicit conversion, there is no other conversion of an anonymous method, even for the Object type, in addition to any implicit conversion of the entrustment type.
The following example illustrates these rules: DELEGATE VOID D (INT X); D D1 = Delegate {}; // OKD D2 = Delegate () {}; // error, signature does not match D D3 = delegate (long x) { }; // error, signature does not match D D4 = delegate (int x) {}; // okd D5 = delegate (int x) {return;}; // okd d6 = delegate (int x) {returnix x;} ; // Error, return type does not match Delegate Void E (Out INT X); E E1 = Delegate {}; // Error E has output parameter E E2 = delegate (out int x) {x = 1;}; // OKE E3 = Delegate (Ref INT X) {x = 1;}; // Error, signature does not match Delegate Int P (params INT [] a); p p1 = delegate {}; // error, block end point P p2 = delegate {return;}; // error, return type does not match P p3 = delegate {return 1;}; // okp p4 = delegate}; // "hello";}; // error, return type does not match P p5 = delegate (int [] a) {// ok return a [0];}; p p6 = delegate (params int [] a) {// error, has params modifier Return a [0];}; P p7 = delegate (int [] a) {// error, return type does not match if (a.length> 0) Return A [0]; return "hello";}; delegate Object q (params int [] a); Q Q1 = delegate (int [] a) {// ok if (a.length> 0) Return A [0) ]; Return "Hello";}; 21.3.1 Entrusted Creating Expressions Delegate Creating Expressions [DELEGATE-CREATION-Expression (7.5.10.3)] can be used as an alternative syntax for converting an anonymous way to a delegate type. If the expression of the argument to create an expression is an anonymous method expression, the anonymous method will use the implicit conversion rules defined above to a given delegate type. For example, if D is a delegate type, the expression new d ("Hello";}) is equivalent to (d) delegate {console.writeline ("hello");}
21.4 Anonymous Method Block Anonymous Method Expression The block follows the following rules: l If the anonymous method contains the signature, the parameters specified in the signature are valid. If an anonymous method does not have a signature, it can be converted to a delegate type (§ 21.3), but the parameters are not accessible within the block. l In addition to the REF and OUT parameters (if any) specified in the closest closed anonymous method (if any), for blocks, accessing the REF or OUT parameters will cause compilation errors. l When this type is a structural type, for blocks, accessing this will result in compile time errors. Whether it is explicit (like this.x) or implicit (like X) in a member of the structural instance, the situation is all. This rule is only forbidden to ban such access, but does not affect the results of the member lookups in the structure. The L block can access the external variable of anonymous method (§ 21.5). When an anonymous method expression is calculated (§ 21.6), the access to the external variable will be referenced to an instance of the activated variable. l For blocks, a GOTO statement, BREAK statement, or a continue statement within the block, or an embedded anonymous method, will result in compile time errors. l The RETURN statement in the block will return control from the closest closed anonymous method call, not returned from the closed function member. The expression specified in the RETURN statement must be compatible with a delegate type, and the closest anonymous method expression will be converted to the delegate type (§ 21.3). Execute the block of an anonymous method, in addition to whether there is any other method in addition to the calculation and calling of anonymous method, there is still other methods, and not clearly explained. In particular, the compiler can implement anonymous method by synthesizing one or more naming methods or types, the name of any such synthetic element, must be used for the compiler to keep in one place: The name must keep two consecutive Tinaby. 21.5 External variable scope contains any local variables, value parameters, and parameter arrays of an anonymous method, which are called an anonymous method expression external variable. Among the instance function members of the class, the THIS value is considered a value parameter, which is also an external variable containing any anonymous method express in the function member.
21.5.1 Capture External Variable When the external variable is quoted by anonymous method, it can be said that this external variable is captured by an anonymous method (Capture). Typically, the living period of the local variable is limited to the execution area of the block or statement it associated (§ 5.1.7). However, the survival of the captured external variable will be at least extended until the commission of anonymous methods can be taken as garbage. Example Using System;
Delegate Int D ();
Class test {static d f () {int x = 0; d result = delegate {Return x;} return result
Static void
Main
() {D = f (); console.writeline (d ()); console.writeLine ()); console.writeLine (D ());}}
The local variable X is captured by an anonymous method, and the survival period of X is at least extended until the delegate returned from f, can be received by garbage (here, this until the program is finally satisfied), since each call of anonymous methods Operation on the same instance of X, the result of this example output is: 123 When the local variable or value parameter is captured by anonymous method, the local variable and value parameter will no longer be considered a fixed (FIXED) variable ( §18.3), in contrast, it is a movable variable. Therefore, any unsafe code that acquires the captured external variable address must first secure the variable using the Fixed statement. 21.5.2 Local Variables Instantiate When the program executes the scope of the variable, local variables are considered instantiated. For example, when the method is called, the local variable will be three instantiated and initialized - each iteration in the loop is once. Static void f () {for (int i = 0; i <3; i ) {int x = i * 2 1; ...}}
However, if the X's declaration is removed from the loop, it will only generate an instantiation for X. Static void f () {int x; for (int i = 0; i <3; i ) {x = i * 2 1; ...}} usually, we cannot see a local variable how long it is exemplified Once - because the instantiated life is disadjoint, it is possible that each instantiation is just the same storage location. However, when an anonymous method captures a local variable, the impact of instantiation will become apparent. Sample Using System;
Delegate void d ();
Class test {static d [] f () {d [] result = new d [3]; for (int i = 0; i <3; i ) {int x = i * 2 1; result [i] = Delegate {console.writeLine (x);};} Return Result
Static void
Main
() {FOREACH (D D IN f ()) d ();}}
Produces the following output. 135 But if the declaration of X is moved to the loop STATIC D [] f () {d [] result = new d [3]; int x; for (int i = 0; i <3; i ) {x = i * 2 1; result [i] =
Del
Egate {console.writeline (x);};} Return Result;} It is as follows. 555 Please note that the three entrustments created in the new version of F are equivalent to equal operators (§21.7). Also, the compiler (but not required) is allowed to optimize three instances into a single entrustment instance (§ 21.6). You can entrust an anonymous way to share some of the captured variables with other separate instances. For example, if F is changed static d [] f () {d [] result = new d [3]; int x = 0; for (int i = 0; i <3; i ) {int y = 0; Result [I] = delegate {console.writeline ("{0} {1}", x, y);};} return result;} These three delegates captured the same example of X, but captured Y Multiple separate instances, so the output is as follows. 1 12 13 1 A separate anonymous method can capture the same example of external variables. For example, Using System; delegate void setter; delegate int getter (); class test {static void main () {int x = 0; setter s = delegate (int value) {x = value;}; getter g = Delegate {RETURN X;}; s (5); console.writeline (g ()); s (10); console.writeline (g ());}} Two anonymous methods captured the same example of local variable x, And they can "communicate" through this variable. This example is output as follows. 510 21.6 Anonymous Method Calculates an anonymous method to express a trial of the trial to generate a commissioned instance of an anonymous method, and the collection of the captured external variable (possibly) is active when calculating (Active) ). When the entrustment generated by anonymous method expression is called, an anonymous method is executed. The code in the method will be performed using the external variable captured by the delegate reference. The delegate call list generated when expressed by anonymous methods contains a single entry. The exact target object and objective method of the commission are not specified. It is important to note whether the delegated target object is NULL, as well as the THIS value of the enclosed function member, or other objects are not specified. The calculation of the same anonymous method in semantics, if they have the same captured external variable set (possibly empty), (but not necessarily) returns the same entrust example. The term "semantically" is used herein, meaning that the operation period of the anonymous method is generated in all cases, the same effects are produced. This rule allows optimization of code as follows. DELEGATE DOUBLE FUNCTION (Double X); Class Test {Static Double [] Apply (Double [] A, Function F) {Double [] Result = New Double [A.Length]; for (INT i = 0; i