C # 2.0 specification (anonymous method) (ii)

Source: Internet
Author: User
Tags filter anonymous data structures expression instance method variables microsoft c
21.7 Delegate instance Equality
The following rules apply the equality operator (§7.9.8) and object of an anonymous method delegate instance. The result of the Equals method.

l When a delegate instance is computed by an anonymous method expression that has the same semantics as the collection of captured external variables, it can be said (but not necessarily) that they are equal.

l When a delegate instance is represented by an anonymous method expression with different semantics, or with a different set of captured external variables, they are never equal.



21.8 Definite assigned value
The explicit assignment state of an anonymous method parameter is the same as the named method. That is, reference parameters and value parameters are explicitly assigned initial values, and output parameters do not have to assign an initial number. Also, the output parameter must be definitely assigned (§5.1.6) before the anonymous method returns normally.

When the control converts to the block of an anonymous method expression, the definite assignment state of the external variable v is the same as the definite assignment state of v before the anonymous method expression. That is, an explicit assignment of an external variable is inherited from the anonymous method expression context. Within an anonymous method block, an explicit assignment is interpreted as if it were in a normal program block (§5.3.3).

The definite assignment state of a variable v after an anonymous method expression is the same as its definite assignment state before an anonymous method expression.



For example

delegate bool Filter (int i);

void F () {
int Max;

Error, Max is not definitely assigned
Filter f = delegate (int n) {return n < max;}

max = 5;
DoWork (f);
}

A compile-time error will occur because Max is not explicitly assigned where the anonymous method declaration is. Example

delegate void D ();

void F () {
int n;
D d = delegate {n = 1;};

D ();

Error, n not definitely assigned
Console.WriteLine (n);
}

Also produces a compile-time error because the assignment of n within an anonymous method has no effect on the explicit assignment state of the external N of the anonymous method.

21.9 Method Group Conversions
Similar to the implicit anonymous method conversion described in §21.3, there is an implicit conversion from the method group (§7.1) to the compatible delegate type.

For a given method group E and delegate type D, if a delegate creation expression (§7.5.10.3 and §20.9.6) in the form of new D (e) is allowed, there is an implicit conversion from E to D, and the result of the conversion is exactly equivalent to new D (e).

In the following example

Using System;
Using System.Windows.Forms;

Class Alertdialog
{
Label message = new label ();
Button OKButton = New button ();
Button CancelButton = New button (); '





Public Alertdialog () {
Okbutton.click + = new EventHandler (Okclick);
Cancelbutton.click + = new EventHandler (Cancelclick);
...
}

void Okclick (object sender, EventArgs e) {
...
}

void Cancelclick (object sender, EventArgs e) {
...
}
}

The constructor creates two delegate instances with new. Implicit method group conversion allows it to be simplified to

Public Alertdialog () {
Okbutton.click + = Okclick;
Cancelbutton.click + = Cancelclick;
...
}

For all other implicit and explicit conversions, the conversion operator can be used to explicitly perform a particular conversion. To do this, the example

Object obj = new EventHandler (Mydialog.okclick);

Can be substituted for the following.

Object obj = (EventHandler) Mydialog.okclick;

method to combine anonymous method expressions can affect overload resolution (overload resolution), but they do not participate in type inference. See §20.6.4 for more detailed information.



21.10 Implementation Examples
This section describes the possible implementations of anonymous methods in the form of standard C # artifacts. The implementation described here is based on the same principles used by the Microsoft C # compiler, but it is by no means a mandatory or only possible implementation.

The following sections of this section give a few sample code that contains anonymous methods with different characteristics. For each example, we will provide a corresponding conversion of the code using the unique standard C # widget. In these examples, the identifier D assumes that the following delegate type is represented.

public delegate void D ();



The simplest form of anonymous method is the one that does not capture external variables.

Class Test
{
static void F () {
D d = delegate {Console.WriteLine ("Test");};
}
}

This code can be converted to a delegate instance that references a static method generated by the compiler, and the code for the anonymous method is placed in the static method. 、

Class Test
{
static void F () {
D d = new D (__METHOD1);
}

static void __method1 () {
Console.WriteLine ("Test");
}
}



In the following example, an anonymous method refers to an instance member of this.

Class Test
{
int x;

void F () {
D d = Delegate {Console.WriteLine (x);};
}
}

This can be converted to an instance method generated by the compiler that contains anonymous method code.

Class Test
{
int x;

void F () {
D d = new D (__METHOD1);
}

void __method1 () {
Console.WriteLine (x);
}
}

In this example, the anonymous method captures a local variable.





Class Test
{
void F () {
int y = 123;
D d = delegate {Console.WriteLine (y);};
}
}

The lifetime of this local variable must now be extended at least until the lifetime of the anonymous method delegate. This can be done by lifting the local variable "promote ()" to the field of the compiler-generated (compiler-generated) class. The instantiation of a local variable corresponds to creating an instance of a compiler-generated class, and accessing a local variable corresponds to accessing a field of the compiler-generated class instance. Also, the anonymous method becomes the instance method of the compiler-generated class.

Class Test
{
void F () {
__LOCALS1 = new __LOCALS1 ();
__LOCALS1.Y = 123;
D d = new D (__LOCALS1.__METHOD1);
}

Class __LOCALS1
{
public int y;

public void __method1 () {
Console.WriteLine (y);
}
}
}

Finally, the following anonymous method captures this and two local variables with different lifetimes.

Class Test
{
int x;

void F () {
int y = 123;
for (int i = 0; i < i++) {
int z = i * 2;
D d = Delegate {Console.WriteLine (x + y + z);};
}
}
}



Here, the compiler generates classes for each statement block in which local variables are captured, while local variables in different blocks will have independent lifetimes.



__LOCALS2 instance, the compiler generates a class for the internal statement block, containing the local variable z and the field referencing the __LOCALS1 instance. __LOCALS1 instance, the compiler generates a class for the outer statement block, contains the local variable y and the field that references the enclosing function member. With these data structures, you can reach all the captured local variables through an instance of __LOCALS2, and the code for the anonymous method can be implemented as an instance method of that class.

Class Test
{
void F () {
__LOCALS1 = new __LOCALS1 ();
__locals1.__this = this;
__LOCALS1.Y = 123;
for (int i = 0; i < i++) {
__LOCALS2 = new __locals2 ();
__LOCALS2.__LOCALS1 = __LOCALS1;
__LOCALS2.Z = i * 2;
D d = new D (__LOCALS2.__METHOD1);
}
}

Class __LOCALS1
{
Public Test __this;
public int y;
}

Class __LOCALS2
{
Public __LOCALS1 __locals1;
public int z;

public void __method1 () {
Console.WriteLine (__locals1.__this.x + __locals1.y + z);
}
}
}

(End of anonymous method)


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.