ares_games
ares_games

Reputation: 1067

How to use parameters for lambda expressions correctly in C#?

I was wondering, if I use Lambda expressions correctly in the following short code snippet? I want to store function calls over time and then execute them all together in Update_Calls(). Most importantly, I am asking whether the parameters var1-3 keep their value (the value they had when calling Extern_Func()) in ANY case?

static List<Action> callsForUpdate = new List<Action>();

public static void Extern_Func(int var1, int var2, float var3)
{
  Action callToStore = () => Func(var1, var2, var3);

  // Remember in call list
  callsForUpdate.Add(callToStore);
}

public static void Update_Calls()
{
  for (int i = 0; i < callsForUpdate.Count; i++)
  {
  callsForUpdate.ElementAt(i);
  }

  callsForUpdate.Clear();
}

Upvotes: 0

Views: 82

Answers (4)

InBetween
InBetween

Reputation: 32760

Closures capture variables, not values. Make sure that is clear.

In your case, var1, var2 and var3 are passed by value arguments that can only be changed locally. Therefore if you don't change them inside Extern_Func you are good to go.

To understand the difference between capturing values or variables, consider the following snippet:

var funcs = new List<Action>();

for (var i = 0; i < 5; i++)
{
    var temp = i;
    funcs.Add(() => Console.WriteLine(i));
    funcs.Add(() => Console.WriteLine(temp));
}

foreach (var f in funcs)
{
    f();
}

Can you guess the output?

Upvotes: 1

Brian Habrock
Brian Habrock

Reputation: 91

What you are doing is creating an expression pointed to by each item in the callsForUpdate list. Expressions are immutable. In order to change the values you supplied in an expression, the expression must be replaced by a new expression with new values.

In my best estimation of what you are asking is true for most any case because your list is simply a list of expressions to be executed with the values supplied at the time they were created by Etern_Func.

Upvotes: 1

Vijay
Vijay

Reputation: 543

Yes. They will be retained. Your Update_Calls has an issue.

    public static void Update_Calls()
    {
        for (int i = 0; i < callsForUpdate.Count; i++)
        {
            callsForUpdate.ElementAt(i)();
        }

        callsForUpdate.Clear();
    }

You were only referring the element. Not calling it.

Upvotes: 2

CrudaLilium
CrudaLilium

Reputation: 672

What you are creating is called Closure, which means that Action will be called with the current values of var1, var2, var3, in this case they are local variables of Extern_Func, so unless you change them in that method (Extern_Func) they will keep their value.

Upvotes: 1

Related Questions