473,395 Members | 1,568 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Possible anonymous method implementation bug?

Okay guys,

We are wondering if this is a bug in Framework 2.0.40607 and
looking for some clarification on the issue. Take a look at the folowing
code.

public delegate bool BoundryTest(int myVal);

public sealed class Idleness

{

public void Work()

{

int limit = 10;

BoundryTest infinite = delegate(int myVal) { return true; };

BoundryTest finite = delegate(int myVal) { return myVal <
limit; };

limit = 20;

WriteEnumeration(Range(0, finite));

for (; limit < 40; limit++)

;

}

private IEnumerable Range(int lowerBoundry, BoundryTest
boundryDelegate)

{

for (int i = lowerBoundry; boundryDelegate(i); i++)

yield return i;

}

private void WriteEnumeration(IEnumerable list)

{

foreach (object o in list)

Console.WriteLine(o.ToString());

}

}

After reading Juval Lowy's article in the May 2004 issue of MSDN Magazine
entitled "C# 2.0 Create Elegant Code with Anonymous Methods, Iterators, and
Partial Classes" we thought we had a handle how this particular code would
behave. So let me summerize what we understood from Juval's explation of the
implementation of anonymous methods.

The Compiler generates different code based on the anonymous method's use of
values from it's containing method or class. If the anonymous method uses no
values other than it's parameters and local variables (those defined inside
the anonymous method itself), then the compiler generates a static method
that has an identical signature to the delegate's requirement, creates a
variable of the delegate type and assignes the value of the delegate
variable to the introduced static method of the class.

If, on the other hand, the anonymous method uses "outer variables", that is,
those that belong to either the containing method or members of the
containing class, the code that gets generated is a bit different. First
off, the compiler generates an inner class that contains a method whose
signature matches the delegate's signature requirement. Additionally
created are: a "<this>" back pointer to the instance of the containing
class, and public member variables for each outer variable (local to the
containing method) that is used in the anonymous method. In the containing
method where the anonymous method was created, the compiler generates
symantically equivalent code. It creates an instance of the introduced inner
class, copies the necessary values of the methods local variables into the
member variables of the introduced inner class, then creates a variable of
the delegate type, assigns the inctroduced inner class's method (which
matches the delegate' s signature requirement) to the delegate variable and
from then on, simply invokes the delegate.

Okay ... that was a mouthful. But! here's the thing... what we described
above is how we expected the the code to be generated, and therefore had a
particular expectation of how the code would behave. We expected the
application to output the intergers in the range 0 to 9. In actuality the
code behaved contrary to what we expected, instead, intergers in the range 0
to 19 were generated ... This confused us a bit so we took a look at what
was generated and here it is.

public void Work()

{

bool flag1;

c__DisplayClass3 class1 = new c__DisplayClass3();

class1.limit = 10;

if (Idleness.__CachedAnonymousMethodDelegate2 == null)

{

Idleness.__CachedAnonymousMethodDelegate2 = new
BoundryTest(Idleness.Workb__0);

}

BoundryTest test1 = Idleness.__CachedAnonymousMethodDelegate2;

BoundryTest test2 = new BoundryTest(class1.Workb__1);

class1.limit = 20;

this.WriteEnumeration(this.Range(0, test2));

while (class1.limit < 40)

{

c__DisplayClass3 class2 = class1;

class1.limit = (class2.limit + 1);

}

}

What we see from the compiled code (which we got from Reflector 4.0 BTW) is
that our "local variable" limit has been implemented as a member variable of
the introduced inner class.

What we see is that in every use of the "local variable" limit in the
original method body has been replaced by use of the introduced inner
class's member variable limit (class1.limit). Which means any changes to the
value of "local variable" limit is visible to invocations of the delegate.

This behavior is not what is expected because this means that changes to the
"local variable" ought not to be visible to methods other than the one in
which it is declared. Our question is ... Is this the intended behavior or
is this in fact a bug? Is the intention to bind the variables in that way?

Cordell Lawrence [cl*******@teleios-systems.com]
Nov 16 '05 #1
0 1619

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
by: Doug Holton | last post by:
Is there any metaclass trick or something similar to allow anonymous code blocks? I'd like to be able to let users do something like this fictitious example: b = Button() b.OnClick =: print...
3
by: anonymous | last post by:
I believe I ran into an interesting way to create memory leaks in C# 2.0 using anymous delegates. Here is a sample of the code in question. private void Handle_Event(object sender, EventArgs e)...
6
by: Anders Thomsen | last post by:
Hi, Is it possible on VB.NET to create anonymous arrays, e.g. passing arrays directly as a method-parameter instead of reference it from a variable. In C#, I can do this: string s = "Blah...
9
by: John Smith | last post by:
I really can not appreciate why Microsoft has introduced Anonymous methods. It promotes quick and dirty style of programming and as I can see it offers no advantages over normal methods. I have...
4
by: Zark3 | last post by:
Hi all, I was wondering if anybody could enlighten me on the possibility of dynamic casting. Or, well, whether or not I'm actually trying to do this the right way. What I have is a base class...
60
by: jacob navia | last post by:
Gnu C features some interesting extensions, among others compound statements that return a value. For instance: ({ int y = foo(); int z; if (y>0) z = y; else z=-y; z; }) A block enclosed by...
4
by: Frankie | last post by:
I have just gotten up to speed on what anonymous methods are (syntax, capabilities, etc), and how they can be used with /called via delegates. What I am wondering is... 1. Are they only/mostly...
3
by: Robert Howells | last post by:
Is there any such thing as an "anonymous delegate"? I understand what an anonymous method is, but I'm unclear of the concept of anonymous delegate (if it is even a valid term to be using). Is an...
0
by: Peter Duniho | last post by:
On Mon, 01 Sep 2008 16:14:10 -0700, Blip <blip@krumpli.comwrote: Briefly, an anonymous method is exactly that: a method without a name. When you use the "delegate" keyword to declare an...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.