When are properties in closures evaluated? - c#

Several methods in our code base use a 'MaybeObject' that can be passed into functions when a result might be known, or might rely on an external webservice call that has not yet been carried out. For example, the property below can either have a specified known value, or if not specified and called after the async call is complete it will return the result of the Async call.
private string _internalString;
public string stringProp
{
get
{
if (!string.IsNullOrEmpty(_internalString))
return _internalString;
return resultOfAsyncCallFromSomewhereElse;
}
set { _internalString = value; }
}
Obviously, trying to reference the property before the async call is complete would cause a null reference exception so we also have a flag to check if the value is available.
The question is, in the code below would the creation of the lambda try and evaluate stringProp (which might not be populated yet), or would evaluation be deferred until the resulting Action is called (which would be after checking the async operation is complete)?
public Action ExampleMethod(MaybeObject maybe)
{
return () => doSomethingWithString(maybe.stringProp);
}

In C# all would be evaluated whilst execution since C# lambda Closures is not a true Closure which able to resolve a state of captured environment in moment of creation.
() => doSomethingWithString(maybe.stringProp);
Here is even reference maybe could be null and you won't got any issues like NullReferenceException until executing a delegate. This trick sometimes used for late-bound value resolving.
Wikipedia: Closure:
A closure retains a reference to the environment at the time it
was created (for example, to the current value of a local variable
in the enclosing scope) while a generic anonymous function need not do
this.
Nice overview of C# Closure specifics - Anonymous methods and closures in C#
From the definition of Closure it can be inferred that Closure
remembers the values of the variables during its creation. However in
C# the outer local variable (i in this case) is shared with the
anonymous method by creating it on the heap. This means any change to
it in the anonymous method changes the original value and when the
method is called the second time it gets the modified value of i as 1
(see second line of output). This leads many to argue that anonymous
method is not actually a Closure as by its definition the value of a
variable at the time of creation of the Closure should be remembered
and not modifiable.

Evaluation will be deferred until the resulting Action is called.
The code referenced by a delegate is only executed when the delegate itself is explicitly invoked, regardless of how the delegate itself was created.
For example, these ways of passing the code to execute through the Action delegate are all equivalent, and the doSomethingWithString method won't be executed until a call to Action() is made:
Explicit method (.NET 1.1):
private MaybeObject maybe;
public Action ExampleMethod()
{
return new Action(DoSomethingWithMaybeObject);
}
private void DoSomethingWithMaybeObject()
{
doSomethingWithString(maybe.stringProp)
}
Anonymous method (.NET 2.0):
public Action ExampleMethod(MaybeObject maybe)
{
return delegate() { doSomethingWithString(maybe.stringProp) };
}
Lambda (.NET 3.5):
public Action ExampleMethod(MaybeObject maybe)
{
return () => doSomethingWithString(maybe.stringProp);
}
See also:
Delegates
Anonymous Methods
Lambda Expressions

Properties in closures are not evaluated until the action is run because properties are methods, not values. Accessing MyObject.MyProperty is like calling the code MyObject.get_MyProperty(), so you can get different behavior when using a property vs. using the underlying variable.

In .net closures are passed as reference so they are executed as they are evaluated, the same reason you can do something like this.
EventHandler handler = null;
handler = (sender, args) => { // event handler do something};
SomeEvent += handler;

it would be deffered.
ExampleMethod() returns a delegate to the anonymous function () => doSomethingWithString(maybe.stringProp), so doSomethingWithString() won't be called until that delegate is called

You should try this yourself to see what happens!
In this case it seems the closure is really around the MaybeObject, not just the string property (because the object is passed to the Action). The string property is not accessed until the Action is executed.
But even if the string itself were the variable given to the closure...
string s = "";
Func<bool> isGood = () => s == "Good";
s = "Good";
Console.WriteLine(isGood());
// prints 'True'
You can see here that the closure is made around a string, but it isn't evaluated until execution.
Delegates work just like any other function - they don't actually do anything until they are called.

Related

What is the value being passed into this lambda expression?

Forgive me if this is a stupid question but I am not sure where to look. I have this code that compiles fine:
static int Main(string[] args)
{
var parserResult = CommandLine.Parser.Default.ParseArguments<Options>(args);
parserResult.WithParsed<Options>(options => OnSuccessfulParse(options));
parserResult.WithNotParsed<Options>(errs =>
{
var helpText = HelpText.AutoBuild(parserResult, h =>
{
return HelpText.DefaultParsingErrorsHandler(parserResult, h);
}, e =>
{
return e;
});
Console.WriteLine(helpText);
ReturnErrorCode = ErrorCode.CommandLineArguments;
});
return (int)ReturnErrorCode;
}
My query has to do with this line of code:
parserResult.WithParsed<Options>(options => OnSuccessfulParse(options));
I understand that with a Lambda Expression the value on the left of the => is the value and value on the right is the expression.
What exactly is options? Why does it compile? It works absolutely fine. But what is it?
I don't know if this helps:
I might be barking up the wrong tree with my understanding of this. I admit I am struggling with the concept. Any explanation appreciated.
I see several questions but I can't explain it in my situation.
Update
OnSuccessfulParse declaration is:
private static void OnSuccessfulParse(Options options)
The WithParsed code is provided here
Lambda expression is the delegate of type Action<Options>. It is a callback from the parser into your code to inform you that the parse has been successful, and pass you Options object obtained as the result of the parse.
As far as options goes, it's just a name that you picked for the parameter to be passed into OnSuccessfulParse method. It is completely unnecessary here - this method group equivalent call will compile and run just the same:
parserResult.WithParsed<Options>(OnSuccessfulParse);
Here is the definition of WithParsed<T> method from github project:
public static ParserResult<T> WithParsed<T>(this ParserResult<T> result, Action<T> action)
{
var parsed = result as Parsed<T>;
if (parsed != null) {
action(parsed.Value);
}
return result;
}
This method is rather straightforward: it takes parse result, tries casting it to a successful parse, and if the cast is valid, calls a delegate that you supply. The WithNotParsed<T> method casts to unsuccessful NotParsed<T> result, and makes a call if the cast is valid.
That's a C# (.Net) way of representing function blocks.
Essentially an Action<Type> is an invocable type that roughly means pass an instance of Type in and execute the block.
E.g. we can write
public void Do(){
this.CallStuff(s => Console.WriteLine(s)); // or you can use a method group and do this.CallStuff(Console.WriteLine);
}
public void CallStuff(Action<string> action){
var #string = "fancy!";
action(#string);
}
In this case the s type is string.
In your example there is a type called Options defined somewhere and it is passed into an action.
Additionally, if you look at decompiled code, anonymous method blocks passed to actions are compiled as static anonymous types inside your class (because c# does not support dynamic code blocks, like, for example, obj-c does).
Another thing to look into are Func<out type> -> these are essentially the same as Action<> except the LAST type in the generic definition is the type they return.
UPD
#elgonzo raises a good point - Action<> and Func<> are actually just delegates; meaning that you can define a real method and pass it along as an Action or Func and then no anonymous static class will be compiled.
However in practice you will see that a lot of code defines those inline, and then the in-line code block needs to reside within a method somewhere, so the compiler puts it into the statis anonymous class.
What exactly is options?
options is i/p parameter to delegate represented by lambda expression
Why does it compile?
Simply because it adheres all syntactical and semantic rules of compiler ;) Like (x)=>x+1 is lambda expression to represent Func<int,int> (there can be another delegate to match same signature as well)
If your method expects Func<int,int> as parameter and argument passed is (x)=>x+1 then compiler infers this as x of type int. Compiled IL code would be equivalent to passing instance of delegate as an argument to method. Like :
call((x)=>x+1) will be compiled to call(new Func<int,int>(myMethod)) where call method definition is :
void Call(Func<int,int> someparam) {}
But what is it?
I think above response should have addressed this query.

How does MethodInvoker gets access to members outside its scope?

public void SomeMethod()
{
List<string> someList = LoadList();
if(condition)
{
MethodInvoker invokeThis = delegate {
someList.Remove(0);
};
if(this.InvokeRequired)
{
this.invoke(invokeThis);
}
else
{
invokeThis();
}
}
}
What I dont understand is how does invokeThis gets access to someList. Shouldnt the scope be limited to delegate { .. };.
No, the access shouldn't be limited to the delegate { ... } block. This is a large part of the benefit of anonymous functions (anonymous methods and lambda expressions) - they're able to capture local variables as part of their environment. In this way they implement closures for C#. Note that these really are variables - if you change the value within the delegate, and then access it within the rest of the method again, you'll see the new value. The variable can live on even after the method has returned, and you can even have multiple "instances" of a local variable - one each time the declaration is logically executed.
See section 7.15.5.1 of the C# 4 spec for more details.
When you have an anonymous delegate or lambda that accesses variables from the function that defines it, the C# compiler automatically restructures your code.
Specifically, it generates a class to hold the locals of that method that is passed to the lambda. You can see this if you inspect the generated code using something like ildasm, Reflector or ILSpy.

Why are lambda expressions not "interned"?

Strings are reference types, but they are immutable. This allows for them to be interned by the compiler; everywhere the same string literal appears, the same object may be referenced.
Delegates are also immutable reference types. (Adding a method to a multicast delegate using the += operator constitutes assignment; that's not mutability.) And, like, strings, there is a "literal" way to represent a delegate in code, using a lambda expression, e.g.:
Func<int> func = () => 5;
The right-hand side of that statement is an expression whose type is Func<int>; but nowhere am I explicitly invoking the Func<int> constructor (nor is an implicit conversion happening). So I view this as essentially a literal. Am I mistaken about my definition of "literal" here?
Regardless, here's my question. If I have two variables for, say, the Func<int> type, and I assign identical lambda expressions to both:
Func<int> x = () => 5;
Func<int> y = () => 5;
...what's preventing the compiler from treating these as the same Func<int> object?
I ask because section 6.5.1 of the C# 4.0 language specification clearly states:
Conversions of semantically identical
anonymous functions with the same
(possibly empty) set of captured outer
variable instances to the same
delegate types are permitted (but not
required) to return the same delegate
instance. The term semantically
identical is used here to mean that
execution of the anonymous functions
will, in all cases, produce the same
effects given the same arguments.
This surprised me when I read it; if this behavior is explicitly allowed, I would have expected for it to be implemented. But it appears not to be. This has in fact gotten a lot of developers into trouble, esp. when lambda expressions have been used to attach event handlers successfully without being able to remove them. For example:
class EventSender
{
public event EventHandler Event;
public void Send()
{
EventHandler handler = this.Event;
if (handler != null) { handler(this, EventArgs.Empty); }
}
}
class Program
{
static string _message = "Hello, world!";
static void Main()
{
var sender = new EventSender();
sender.Event += (obj, args) => Console.WriteLine(_message);
sender.Send();
// Unless I'm mistaken, this lambda expression is semantically identical
// to the one above. However, the handler is not removed, indicating
// that a different delegate instance is constructed.
sender.Event -= (obj, args) => Console.WriteLine(_message);
// This prints "Hello, world!" again.
sender.Send();
}
}
Is there any reason why this behavior—one delegate instance for semantically identical anonymous methods—is not implemented?
You're mistaken to call it a literal, IMO. It's just an expression which is convertible to a delegate type.
Now as for the "interning" part - some lambda expressions are cached , in that for one single lambda expression, sometimes a single instance can be created and reused however often that line of code is encountered. Some are not treated that way: it usually depends on whether the lambda expression captures any non-static variables (whether that's via "this" or local to the method).
Here's an example of this caching:
using System;
class Program
{
static void Main()
{
Action first = GetFirstAction();
first -= GetFirstAction();
Console.WriteLine(first == null); // Prints True
Action second = GetSecondAction();
second -= GetSecondAction();
Console.WriteLine(second == null); // Prints False
}
static Action GetFirstAction()
{
return () => Console.WriteLine("First");
}
static Action GetSecondAction()
{
int i = 0;
return () => Console.WriteLine("Second " + i);
}
}
In this case we can see that the first action was cached (or at least, two equal delegates were produced, and in fact Reflector shows that it really is cached in a static field). The second action created two unequal instances of Action for the two calls to GetSecondAction, which is why "second" is non-null at the end.
Interning lambdas which appear in different places in the code but with the same source code is a different matter. I suspect it would be quite complex to do this properly (after all, the same source code can mean different things in different places) and I would certainly not want to rely on it taking place. If it's not going to be worth relying on, and it's a lot of work to get right for the compiler team, I don't think it's the best way they could be spending their time.
Is there any reason why this behavior—one delegate instance for semantically identical anonymous methods—is not implemented?
Yes. Because spending time on a tricky optimization that benefits almost no one takes time away from designing, implementing, testing and maintaining features that do benefit people.
The other answers bring up good points. Mine really doesn't have to do with anything technical - Every feature starts out with -100 points.
In general, there is no distinction between string variables which refer to the same String instance, versus two variables which refer to different strings that happen to contain the same sequence of characters. The same is not true of delegates.
Suppose I have two delegates, assigned to two different lambda expressions. I then subscribe both delegates to an event handler, and unsubscribe one. What should be the result?
It would be useful if there were a way in vb or C# to designate that an anonymous method or lambda which does not make reference to Me/this should be regarded as a static method, producing a single delegate which could be reused throughout the life of the application. There is no syntax to indicate that, however, and for the compiler to decide to have different lambda expressions return the same instance would be a potentially breaking change.
EDIT I guess the spec allows it, even though it could be a potentially breaking change if any code were to rely upon the instances being distinct.
This is allowed because the C# team cannot control this. They heavily rely on the implementation details of delegates (CLR + BCL) and the JIT compiler's optimizer. There already is quite a proliferation of CLR and jitter implementations right now and there is little reason to assume that's going to end. The CLI spec is very light on rules about delegates, not nearly strong enough to ensure all these different teams will end up with an implementation that guarantees that delegate object equality is consistent. Not in the least because that would hamper future innovation. There's lots to optimize here.
Lambdas can't be interned because they use an object to contain the captured local variables. And this instance is different every time you you construct the delegate.

C# Cannot use ref or out parameter inside an anonymous method body

I'm trying to create a function that can create an Action that increments whatever integer is passed in. However my first attempt is giving me an error "cannot use ref or out parameter inside an anonymous method body".
public static class IntEx {
public static Action CreateIncrementer(ref int reference) {
return () => {
reference += 1;
};
}
}
I understand why the compiler doesn't like this, but nonetheless I'd like to have a graceful way to provide a nice incrementer factory that can point to any integer. The only way I'm seeing to do this is something like the following:
public static class IntEx {
public static Action CreateIncrementer(Func<int> getter, Action<int> setter) {
return () => setter(getter() + 1);
}
}
But of course that is more of a pain for the caller to use; requiring the caller to create two lambdas instead of just passing in a reference. Is there any more graceful way of providing this functionality, or will I just have to live with the two-lambda option?
Okay, I've found that it actually is possible with pointers if in unsafe context:
public static class IntEx {
unsafe public static Action CreateIncrementer(int* reference) {
return () => {
*reference += 1;
};
}
}
However, the garbage collector can wreak havoc with this by moving your reference during garbage collection, as the following indicates:
class Program {
static void Main() {
new Program().Run();
Console.ReadLine();
}
int _i = 0;
public unsafe void Run() {
Action incr;
fixed (int* p_i = &_i) {
incr = IntEx.CreateIncrementer(p_i);
}
incr();
Console.WriteLine(_i); // Yay, incremented to 1!
GC.Collect();
incr();
Console.WriteLine(_i); // Uh-oh, still 1!
}
}
One can get around this problem by pinning the variable to a specific spot in memory. This can be done by adding the following to the constructor:
public Program() {
GCHandle.Alloc(_i, GCHandleType.Pinned);
}
That keeps the garbage collector from moving the object around, so exactly what we're looking for. However then you've got to add a destructor to release the pin, and it fragments the memory throughout the lifetime of the object. Not really any easier. This would make more sense in C++, where stuff doesn't get moved around, and resource management is par the course, but not so much in C# where all that is supposed to be automatic.
So looks like the moral of the story is, just wrap that member int in a reference type and be done with it.
(And yes, that's the way I had it working before asking the question, but was just trying to figure out if there was a way I could get rid of all my Reference<int> member variables and just use regular ints. Oh well.)
This is not possible.
The compiler will transform all local variables and parameters used by anonymous methods into fields in an automatically generated closure class.
The CLR does not allow ref types to be stored in fields.
For example, if you pass a value type in a local variable as such a ref parameter, the value's lifetime would extend beyond its stack frame.
It might have been a useful feature for the runtime to allow the creation of variable references with a mechanism to prevent their persistence; such a feature would have allowed an indexer to behave like an array (e.g. so a Dictionary<Int32, Point> could be accessed via "myDictionary[5].X = 9;"). I think such a feature could have been provided safely if such references could not be downcast to other types of objects, nor used as fields, nor passed by reference themselves (since anyplace such a reference could be stored would go out of scope before the reference itself would). Unfortunately, the CLR does not provide such a feature.
To implement what you're after would require that the caller of any function which uses a reference parameter within a closure must wrap within a closure any variable it wants to pass to such a function. If there were a special declaration to indicate that a parameter would be used in such a fashion, it might be practical for a compiler to implement the required behavior. Maybe in a .net 5.0 compiler, though I'm not sure how useful that would be.
BTW, my understanding is that closures in Java use by-value semantics, while those in .net are by-reference. I can understand some occasional uses for by-reference semantics, but using reference by default seems a dubious decision, analogous to the use of default by-reference parameter-passing semantics for VB versions up through VB6. If one wants to capture the value of a variable when creating a delegate to call a function (e.g. if one wants a delegate to call MyFunction(X) using the value of X when the delegate is created), is it better to use a lambda with an extra temp, or is it better to simply use a delegate factory and not bother with Lambda expressions.

understand the following lambda

I have a method like
void Test(Func<bool> f)
{
f.Invoke();
}
I pass in the Test( ()=>GetItem("123") )
f.Invoke() actually called GetItem("123").
I want to know how does f know GetItem has a parameter?
Your function Test takes a function as a parameter. It will invoke whatever function is passed in as an argument.
In this case, when you create your lambda () => GetItem("123"), you are creating a function that takes no arguments, and invokes GetItem("123").
Test has no knowledge about the value of the parameter passed to GetItem, nor does it need to, because the value of the parameter is hardcoded in the lambda.
You're question is a bit confusing. F doesn't know what's required by Getitem.
When you created the lambda, a "pointer" was returned to the place in the memory where a method is located. That method contains the line of code return Getitem("123").
When you invoke F, what actually happens is a kind of jump to a pointer. F is like a "pointer" to that place in the memory where the function is located.
So, to answer your question, F doesn't know what Getitem needs, F just calls the function your wrote, and that function has the "123" parameter hard coded.
Remember that lambda is a type of Delegate
What you are passing to Test is a parameter-less delegate which calls your GetItem method.
So your Test method does not know anything about parameters to GetItem. It only knows about the delegate it is calling.
Test( ()=>GetItem("123") )
is equal to
Test(delegate { return GetItem("abc") ; } );
which is like calling
Test(MyMethod)
...
bool MyMethod()
{
return GetItem("123");
}
Good question. You can think of the delegate
() => GetItem("123")
as being a compiled version of the following expression tree
Expression.Lambda<Func<bool>>(
Expression.Call(
null,
typeof(X).GetMethod("GetItem"),
new Expression[] { Expression.Constant("123", typeof(string)) }
),
new ParameterExpression[0]
);
Here I am assuming that GetItem is a method defined in a class X and that its return type is declared as bool.
The point is that the delegate captures all the information it needs to be invoked. When you invoke this delegate in Test, you have no idea that the method GetItem is behind the scenes, or that it is being invoked with the parameter "123". The delegate is keeping track of that information and Test is agnostic to those details. It just wants something that it can invoke that ultimately returns a bool. In your particular instance, that bool happens to be the result of GetItem("123").
f.Invoke() actually called GetItem("123")
Actually it didn't. It called () => GetItem("123") which merely returns the value of GetItem("123"). See the difference?

Categories