Lambda Expressions : Compiler Behaviour - c#

Well I am going through the 'Lambda Expressions' topic (Chapter 17; Delegates, C# Syntactical Sugar for Delegates). Jeffery states that the C# compiler creates a new non-static class in the background that has the following:
Fields to store all the local variables that have been accessed in the Lambda Expression.
A method whose body contains the Lambda Expression and whose signature/return type matches the delegate for which the Lambda Expressin has been used.
I have the following two questions:
I did a little debugging myself and saw that if the Lambda Expression modifies the value of a local variable(defined in a method the lambda Expresison is being used in), the new value is reflected outside the expression body too. How is this possible considering the expression is actually in a different class?
Why does the emitted class need to be non-static when the same can be done by Static class perfectly?
I hope this is not a very simple concept that I am unable to comprehend.
Let me know if I need to provide more details.

First of all i had a similar question, a few days ago.
Closure captured variable modifies the original as well
Second, what is the point of making it a static class? Only one object is created anyway, and that object does not have to live troughout the application lifetime.
the new value is reflected outside the expression body too. How is this possible considering the expression is actually in a different class.
The thing is that the same object is being referenced both by the anonymus method, as well as the local variable outside the anonymus method, so it does not matter from where you change it, you change the same thing.
Also, the answer provided by Tim Goodman in the question i linked to, shows you what to do, in order to avoid changes being reflected everywhere, by creating a new object inside your anonymus method.

Related

use delegate (or other) to do the same thing as lambda operator [duplicate]

I'm new to SO and programming and learning day by day with bits and pieces of tech (C#) jargons.
After Googling for a while, below is what I've researched about methods
A Method is a block of statements, which serves for code reusability
& it also supports overloading with different SIGNATURE....for ex:
drawShape(2pts), drawShape(3pts) etc...
An Anonymous method is one with block of statements, but no
name....(as its premature to ask, in wt situation we come across
anonymous method...any articles, samples ...)
Named method: Here's a link but at the end i didn't get what Named Method actually is...
Can anyone explain what a "Named" method is, and where do we use anonymous method?
A named method is a method you can call by its name (e.g. it is a function that has a name). For example, you have defined a function to add two numbers:
int f(int x, int y)
{
return x+y;
}
You would call this method by its name like so: f(1, 2);.
Anonymous method is a method that is passed as an argument to a function without the need for its name. These methods can be constructed at runtime or evaluated from a lambda expression at compile time.
These methods are often used in LINQ queries, for example:
int maxSmallerThan10 = array.Where(x => x < 10).Max();
The expression x => x < 10 is called a lambda expression and its result is an anonymous function that will be run by the method Where.
If you are a beginner, I would suggest you first read about more basic stuff. Check out the following links:
http://www.completecsharptutorial.com/
http://www.csharp-station.com/tutorial.aspx
http://www.homeandlearn.co.uk/csharp/csharp.html
Let's start from a simple method.
void MyMethod()
{
Console.WriteLine("Inside MyMethod"); //Write to output
}
The above method is a named-method which just writes Inside MyMethod to the output window.
Anonymous methods are some methods used in some special scenarios (when using delegates) where the method definition is usually smaller where you don't specify the name of the method.
For example, (delegate) => { Console.WriteLine("Inside Mymethod");}
Just start writing some simple programs and in the due course, when you use delegates or some advanced concepts, you will yourself learn. :)
Explanation by Analogy
Normally when we tell stories we refer to people by name:
"Freddie"
"Who's Freddie?"
"You know, Freddie, Freddie from Sales - the male guy with the red hair, who burned the building down...?"
In reality nobody cares who the person is, department he works etc. it's not like we'll refer to him every again. We want to be able to say: "Some guy burned down our building". All the other stuff (hair color, name etc.) is irrelevant and/or can be inferred.
What does this have to do with c#?
Typically in c# you would have to define a method if you want to use it: you must tell the compiler (typically):
what it is called,
and what goes into it (parameters + their types),
as well as what should come out (return type),
and whether it is something you can do in the privacy of your home or whether you can do it in public. (scope)
When you do that with methods, you are basically using named methods. But writing them out: that's a lot of effort. Especially if all of that can be inferred and you're never going to use it again.
That's basically where anonymous methods come in. It's like a disposable method - something quick and dirty - it reduces the amount you have to type in. That's basically the purpose of them.
Anonymous methods or anonymous functions, what seems to be the same, basically are delegates. As the link you point out: http://msdn.microsoft.com/en-us/library/bb882516.aspx describes, anonymous methods provide a simplified way to pass method to be executed by another method. Like a callback.
Another way to see it, is think about lambda expressions.
A named by the contrast is any common method.
From MSDN:
A delegate can be associated with a named method. When you instantiate a delegate by using a named method, the method is passed as a parameter. This is called using a named method. Delegates constructed with a named method can encapsulate either a static method or an instance method. Named methods are the only way to instantiate a delegate in earlier versions of C#. However, in a situation where creating a new method is unwanted overhead, C# enables you to instantiate a delegate and immediately specify a code block that the delegate will process when it is called. The block can contain either a lambda expression or an anonymous method.
and
In versions of C# before 2.0, the only way to declare a delegate was to use named methods. C# 2.0 introduced anonymous methods and in C# 3.0 and later, lambda expressions supersede anonymous methods as the preferred way to write inline code. However, the information about anonymous methods in this topic also applies to lambda expressions. There is one case in which an anonymous method provides functionality not found in lambda expressions. Anonymous methods enable you to omit the parameter list. This means that an anonymous method can be converted to delegates with a variety of signatures. This is not possible with lambda expressions. For more information specifically about lambda expressions, see Lambda Expressions (C# Programming Guide). Creating anonymous methods is essentially a way to pass a code block as a delegate parameter. By using anonymous methods, you reduce the coding overhead in instantiating delegates because you do not have to create a separate method.
So in answer to your question about when to use anonymous methods, then MSDN says: in a situation where creating a new method is unwanted overhead.
In my experience it's more down to a question of code reuse and readability.
Links:
http://msdn.microsoft.com/en-us/library/98dc08ac.aspx
http://msdn.microsoft.com/en-us/library/0yw3tz5k.aspx
Hope that helps

C# Opposite of "Anonymous" Function [duplicate]

I'm new to SO and programming and learning day by day with bits and pieces of tech (C#) jargons.
After Googling for a while, below is what I've researched about methods
A Method is a block of statements, which serves for code reusability
& it also supports overloading with different SIGNATURE....for ex:
drawShape(2pts), drawShape(3pts) etc...
An Anonymous method is one with block of statements, but no
name....(as its premature to ask, in wt situation we come across
anonymous method...any articles, samples ...)
Named method: Here's a link but at the end i didn't get what Named Method actually is...
Can anyone explain what a "Named" method is, and where do we use anonymous method?
A named method is a method you can call by its name (e.g. it is a function that has a name). For example, you have defined a function to add two numbers:
int f(int x, int y)
{
return x+y;
}
You would call this method by its name like so: f(1, 2);.
Anonymous method is a method that is passed as an argument to a function without the need for its name. These methods can be constructed at runtime or evaluated from a lambda expression at compile time.
These methods are often used in LINQ queries, for example:
int maxSmallerThan10 = array.Where(x => x < 10).Max();
The expression x => x < 10 is called a lambda expression and its result is an anonymous function that will be run by the method Where.
If you are a beginner, I would suggest you first read about more basic stuff. Check out the following links:
http://www.completecsharptutorial.com/
http://www.csharp-station.com/tutorial.aspx
http://www.homeandlearn.co.uk/csharp/csharp.html
Let's start from a simple method.
void MyMethod()
{
Console.WriteLine("Inside MyMethod"); //Write to output
}
The above method is a named-method which just writes Inside MyMethod to the output window.
Anonymous methods are some methods used in some special scenarios (when using delegates) where the method definition is usually smaller where you don't specify the name of the method.
For example, (delegate) => { Console.WriteLine("Inside Mymethod");}
Just start writing some simple programs and in the due course, when you use delegates or some advanced concepts, you will yourself learn. :)
Explanation by Analogy
Normally when we tell stories we refer to people by name:
"Freddie"
"Who's Freddie?"
"You know, Freddie, Freddie from Sales - the male guy with the red hair, who burned the building down...?"
In reality nobody cares who the person is, department he works etc. it's not like we'll refer to him every again. We want to be able to say: "Some guy burned down our building". All the other stuff (hair color, name etc.) is irrelevant and/or can be inferred.
What does this have to do with c#?
Typically in c# you would have to define a method if you want to use it: you must tell the compiler (typically):
what it is called,
and what goes into it (parameters + their types),
as well as what should come out (return type),
and whether it is something you can do in the privacy of your home or whether you can do it in public. (scope)
When you do that with methods, you are basically using named methods. But writing them out: that's a lot of effort. Especially if all of that can be inferred and you're never going to use it again.
That's basically where anonymous methods come in. It's like a disposable method - something quick and dirty - it reduces the amount you have to type in. That's basically the purpose of them.
Anonymous methods or anonymous functions, what seems to be the same, basically are delegates. As the link you point out: http://msdn.microsoft.com/en-us/library/bb882516.aspx describes, anonymous methods provide a simplified way to pass method to be executed by another method. Like a callback.
Another way to see it, is think about lambda expressions.
A named by the contrast is any common method.
From MSDN:
A delegate can be associated with a named method. When you instantiate a delegate by using a named method, the method is passed as a parameter. This is called using a named method. Delegates constructed with a named method can encapsulate either a static method or an instance method. Named methods are the only way to instantiate a delegate in earlier versions of C#. However, in a situation where creating a new method is unwanted overhead, C# enables you to instantiate a delegate and immediately specify a code block that the delegate will process when it is called. The block can contain either a lambda expression or an anonymous method.
and
In versions of C# before 2.0, the only way to declare a delegate was to use named methods. C# 2.0 introduced anonymous methods and in C# 3.0 and later, lambda expressions supersede anonymous methods as the preferred way to write inline code. However, the information about anonymous methods in this topic also applies to lambda expressions. There is one case in which an anonymous method provides functionality not found in lambda expressions. Anonymous methods enable you to omit the parameter list. This means that an anonymous method can be converted to delegates with a variety of signatures. This is not possible with lambda expressions. For more information specifically about lambda expressions, see Lambda Expressions (C# Programming Guide). Creating anonymous methods is essentially a way to pass a code block as a delegate parameter. By using anonymous methods, you reduce the coding overhead in instantiating delegates because you do not have to create a separate method.
So in answer to your question about when to use anonymous methods, then MSDN says: in a situation where creating a new method is unwanted overhead.
In my experience it's more down to a question of code reuse and readability.
Links:
http://msdn.microsoft.com/en-us/library/98dc08ac.aspx
http://msdn.microsoft.com/en-us/library/0yw3tz5k.aspx
Hope that helps

Why anonymous methods inside structs can not access instance members of 'this'

I have a code like the following:
struct A
{
void SomeMethod()
{
var items = Enumerable.Range(0, 10).Where(i => i == _field);
}
int _field;
}
... and then i get the following compiler error:
Anonymous methods inside structs can not access instance members of 'this'.
Can anybody explains what's going on here.
Variables are captured by reference (even if they were actually value-types; boxing is done then).
However, this in a ValueType (struct) cannot be boxed, and hence you cannot capture it.
Eric Lippert has a nice article on the surprises of capturing ValueTypes. Let me find the link
The Truth About Value Types
Note in response to the comment by Chris Sinclair:
As a quick fix, you can store the struct in a local variable: A thisA = this; var items = Enumerable.Range(0, 10).Where(i => i == thisA._field); – Chris Sinclair 4 mins ago
Beware of the fact that this creates surprising situations: the identity of thisA is not the same as this. More explicitly, if you choose to keep the lambda around longer, it will have the boxed copy thisA captured by reference, and not the actual instance that SomeMethod was called on.
When you have an anonymous method it will be compiled into a new class, that class will have one method (the one you define). It will also have a reference to each variable that you used that was outside of the scope of the anonymous method. It's important to emphasize that it is a reference, not a copy, of that variable. "lambdas close over variables, not values" as the saying goes. This means that if you close over a variable outside of the scope of a lambda, and then change that variable after defining the anonymous method (but before invoking it) then you will see the changed value when you do invoke it).
So, what's the point of all of that. Well, if you were to close over this for a struct, which is a value type, it's possible for the lambda to outlive the struct. The anonymous method will be in a class, not a struct, so it will go on the heap, live as long as it needs to, and you are free to pass a reference to that class (directly or indirectly) wherever you want.
Now imagine that we have a local variable, with a struct of the type you've defined here. We use this named method to generate a lambda, and let's assume for a moment that the query items is returned (instead of the method being void). Would could then store that query in another instance (instead of local) variable, and iterate over that query some time later on another method. What would happen here? In essence, we would have held onto a reference to a value type that was on the stack once it is no longer in scope.
What does that mean? The answer is, we have no idea. (Please look over the link; it's kinda the crux of my argument.) The data could just happen to be the same, it could have been zeroed out, it could have been filled by entirely different objects, there is no way of knowing. C# goes to great lengths, as a language, to prevent you from doing things like this. Languages such as C or C++ don't try so hard to stop you from shooting your own foot.
Now, in this particular case, it's possible that you aren't going to use the lambda outside of the scope of what this refers to, but the compiler doesn't know that, and if it lets you create the lambda it has no way of determining whether or not you expose it in a way that could result in it outliving this, so the only way to prevent this problem is to disallow some cases that aren't actually problematic.

Getting names of local variables (and parameters) at run-time through lambda expressions

I’m interested in retrieving the names of local variables (and parameters) at run-time in a refactor-safe manner. I have the following extension method:
public static string GetVariableName<T>(Expression<Func<T>> variableAccessExpression)
{
var memberExpression = variableAccessExpression.Body as MemberExpression;
return memberExpression.Member.Name;
}
…which returns the name of the variable captured through a lambda expression:
static void Main(string[] args)
{
Console.WriteLine(GetVariableName(() => args));
// Output: "args"
int num = 0;
Console.WriteLine(GetVariableName(() => num));
// Output: "num"
}
However, this only works because the C# compiler promotes any local variables (and parameters) that are captured in anonymous functions to instance variables of the same name within a compiler-generated class behind the scenes (per Jon Skeet). If this were not the case, the cast of Body to MemberExpression would fail, since MemberExpression represents field or property access.
Is this variable promotion documented behaviour, or is it an implementation detail subject to change in other versions of the framework?
Note: This question is a generalization of my former one on argument validation.
Update: This is no longer an issue from C# 6, which has introduced the nameof operator to address such scenarios (see MSDN).
It appears that the answer to my question is no; the feature is non-standardized. The situation seems even bleaker than I’d originally suspected; not only is the promotion of captured variables non-standardized, but so is the entire specification of converting anonymous functions to their expression tree representations.
The implication of this is that even straightforward anonymous functions, such as the below, are not guaranteed to result in consistent expression trees across different implementations of the framework (until the conversion is standardized):
Expression<Func<int, int, int>> add = (int x, int y) => x + y;
The following excerpts are taken from the C# Language Specification 4.0 (emphasis added in all cases).
From “4.6 Expression tree types”:
The exact definition of the generic type Expression<D> as well as the precise rules for constructing an expression tree when an anonymous function is converted to an expression tree type, are both outside the scope of this specification, and are described elsewhere.
From “6.5.2 Evaluation of anonymous function conversions to expression tree types”:
Conversion of an anonymous function to an expression tree type produces an expression tree (§4.6). More precisely, evaluation of the anonymous function conversion leads to the construction of an object structure that represents the structure of the anonymous function itself. The precise structure of the expression tree, as well as the exact process for creating it, are implementation defined.
The third example in “6.5.3 Implementation example” demonstrates the conversion of an anonymous function that captures a local variable, and confirms the variable promotion mentioned in my question:
The lifetime of the local variable must now be extended to at least the lifetime of the anonymous function delegate. This can be achieved by “hoisting” the local variable into a field of a compiler generated class. Instantiation of the local variable (§7.15.5.2) then corresponds to creating an instance of the compiler generated class, and accessing the local variable corresponds to accessing a field in the instance of the compiler generated class.
This is further corroborated at the end of the section:
The same technique applied here to capture local variables can also be used when converting anonymous functions to expression trees: References to the compiler generated objects can be stored in the expression tree, and access to the local variables can be represented as field accesses on these objects. The advantage of this approach is that it allows the “lifted” local variables to be shared between delegates and expression trees.
However, there is a disclaimer at the beginning of the section:
The implementation described here is based on the same principles used by the Microsoft C# compiler, but it is by no means a mandated implementation, nor is it the only one possible. It only briefly mentions conversions to expression trees, as their exact semantics are outside the scope of this specification.
P.S. Eric Lippert confirms in this comment that the expression tree specs were never shipped. There exists an Expression Trees v2 Spec under the DLR documentation on CodePlex, but its scope does not appear to cover the conversion of anonymous functions to expression trees in C#.
This is a behavior you should not rely upon.
Take a look at Abuse of C# lambda expressions or Syntax brilliance?
Now read the comments from Eric Lippert who is on the C# design team. They include:
I just asked Anders (and the rest of the design team) what they
thought. Let's just say the results would not be printable in a
family-friendly newspaper
and
As for why this is horrid, we could start with unobvious, clever
(remember, clever is bad, clever code is hard to maintain), not at all
within the by-design use cases envisaged by the designers of lambdas,
slow, brittle, unportable, and unnecessary
From these statements I would say that it will not become a documented or supported behavior.
AFAIK, it's an implementation detail.
However, I think you can bet it won't actually change.
I just tested in VS2012 RC and it works as expected - so you're safe for a couple of years at least.

C# Debugging functions that contain lambda expressions [duplicate]

This question already has answers here:
Why can I not edit a method that contains an anonymous method in the debugger?
(5 answers)
Closed 6 years ago.
I have a function with a lambda expression something like:
int maxOccurrences = ( from field in data select field ).Max( f => f.Occurrences )
P.S. I'm sure that there's a nicer / neater / more idiomatic version of the above statement, it might be nice to know what that might be, although its not important to the question!
If I modify anything else within the function whilst debugging say a Console.Write expression, the debugger states:
Modifying a 'method' which contains a lambda expression will prevent the debug session from continuing while Edit and Continue is enabled.
I was wondering why this might be the case?
I would have thought that the IL generated for the lamba function and the Console.Write statement would be separate and that the Debugger could alter and modify when necessary. Is there some fundamental concept that I'm missing concerning the lamda functionality?
It isn't that it would be impossible to achieve in all cases (I don't think). It would be a monster feature to develop, though.
When you've got LINQ syntax in your method, generally that involves some anonymous method either behind-the-scenes:
// This LINQ query...
var fields = from field in data select field;
// ...is equivalent to this:
var fields = data.Select(f => f);
...or just flat-out in front of the scenes (as in your example):
( from field in data select field ).Max( f => f.Occurrences ) // <- lambda
An anonymous method in turn gets compiled into a type with instance methods to support the code you've written.
In the example above, consider the f => f.Occurrences lambda. This gets compiled into a type with a single instance field whose type is that of the local f in that lambda; this type contains a method that returns f.Occurrences.
So when the code ultimately enumerates over the result of your LINQ query, what's happening is that an instance of this compiler-generated type is being constructed for every field in data and that type's single method which has been generated to support the f => f.Occurrences lambda expression is being called to calculate Max.
The issue with edit-and-continue is that if there's any change to the lambda expressions in the method being edited, this necessitates changing the types generated, which is not an option. One would think this could still be done in the case where nothing is altered about the lambda expressions themselves; as long as the same locals are captured and the anonymous methods are unchanged, it should be feasible to modify a method with these characteristics while debugging just as it is for "normal" methods in VS.
But as you can see, the type generation used to support anonymous methods in general and therefore LINQ queries specifically adds a great deal of complexity to the edit-and-continue process, and in many cases makes it impossible (since it requires changing generated types completely).
I think it was just decided that it wasn't worth the development cost to even bother trying to support this behavior in the limited scenarios where it could hypothetically work.
Or you can simply move to Visual Studio 2015 :)
The "Edit and Continue" feature in VS 2015 allows editing methods with lambda expressions.
You can read about it in more detail here:
http://blogs.msdn.com/b/visualstudioalm/archive/2015/04/29/net-enc-support-for-lambdas-and-other-improvements-in-visual-studio-2015.aspx
There is a really simple way to debug a lamba expression. Convert it to an anonymous method using an inline delegate. Simple. :)

Categories

Resources