Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Outer Variable Trap

Tags:

c#

linq

What exactly is the Outer Variable Trap? Explanation and examples in C# are appreciated.

EDIT: Incorporating Jon Skeet's diktat :)

Eric Lippert on the Outer Variable Trap

like image 241
GilliVilla Avatar asked Aug 05 '10 16:08

GilliVilla


People also ask

What is the dummy variable trap?

Dummy Variable Trap: When the number of dummy variables created is equal to the number of values the categorical value can take on. This leads to multicollinearity, which causes incorrect calculations of regression coefficients and p-values. For example, suppose we converted marital status into the following dummy variables:

Why is value 5 (trap community string) being logged?

You can see now that Value 5 (Trap community string) now shows the community string of public which was used in the last command. unknown. Previously nothing was logged in here, however now the community string is being logged because the embedded handler is being used.

Why is there no community string in the SNMP v3 trap?

However because we sent an SNMP v3 trap there is no community string involved. Assuming that the embedded handler is still configured as per the last section, try sending an SNMP v2c trap again using the following command: Now execute this command to see the trap that was logged in the /var/log/snmp/snmpttunknown.log file:

How do I test traps in Nagios XI?

The first step is to send the Nagios XI server a test trap to itself. Now execute this command to see the trap that was logged in the /var/log/snmp/snmpttunknown.log file: Looking at the output you can most likely figure out what some of it means, but other information is not so easy to decipher. This is explained in the next section.


3 Answers

The "Outer Variable Trap" occurs when a developer expects the value of a variable to be captured by a lambda expression or anonymous delegate, when actually the variable is captured itself.

Example:

var actions = new List<Action>();
for (var i = 0; i < 10; i++)
{
    actions.Add(() => Console.Write("{0} ", i));
}
foreach (var action in actions)
{
    action();
}

Possible output #1:

0 1 2 3 4 5 6 7 8 9

Possible output #2:

10 10 10 10 10 10 10 10 10 10

If you expected output #1, you've fallen into the Outer Variable Trap. You get output #2.

Fix:

Declare an "Inner Variable" to be captured repeatedly instead of the "Outer Variable" which is captured only once.

var actions = new List<Action>();
for (var i = 0; i < 10; i++)
{
    var j = i;
    actions.Add(() => Console.Write("{0} ", j));
}
foreach (var action in actions)
{
    action();
}

For more details, see also Eric Lippert's blog.

like image 68
dtb Avatar answered Oct 22 '22 16:10

dtb


Something like

foreach (var s in strings)
    var x = results.Where(r => (r.Text).Contains(s));

Will not give the results you're expecting because the Contains is not executed for each iteration. Assigning s to a temporary variable inside the loop will fix this, though.

like image 5
heisenberg Avatar answered Oct 22 '22 17:10

heisenberg


It's worthy to note that this trap existed for foreach loops too but has been changed since C# 5.0, i.e. inside foreach loops closures now close over a fresh copy of the loop variable each time. So the below code:

var values = new List<int>() { 100, 110, 120 };
var funcs = new List<Func<int>>();
foreach (var v in values)
    funcs.Add(() => v);
foreach (var f in funcs)
    Console.WriteLine(f());

Prints 120 120 120 < C# 5.0, but 100 110 120 >= C# 5.0

However for loops still behave the same way.

like image 3
Saeb Amini Avatar answered Oct 22 '22 17:10

Saeb Amini