Skip to content

Instantly share code, notes, and snippets.

@odalet
Last active July 3, 2020 09:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save odalet/6877c04958dc3e0794b25dcf8e719a4d to your computer and use it in GitHub Desktop.
Save odalet/6877c04958dc3e0794b25dcf8e719a4d to your computer and use it in GitHub Desktop.
Lambda Tricks
using System;
using System.Linq;
namespace Rextester
{
// See https://csharp.2000things.com/tag/captured-variable/
internal static class Program
{
public static void Main(string[] args)
{
Console.WriteLine("*******************************");
Console.WriteLine($"{nameof(Test1)} - Simple Lambdas:");
Test1();
Console.WriteLine("*******************************");
Console.WriteLine($"{nameof(Test2)} - Lambdas in foreach loops:");
Test2();
Console.WriteLine("*******************************");
Console.WriteLine($"{nameof(Test3)} - Lambdas in for loops:");
Test3();
Console.WriteLine("*******************************");
Console.WriteLine($"{nameof(Test4)} - Local functions in foreach loops:");
Test4();
Console.WriteLine("*******************************");
Console.WriteLine($"{nameof(Test5)} - Local functions in for loops:");
Test5();
}
private static void Test1()
{
var i = 42;
Console.WriteLine($"{i}");
Action action = () => Console.WriteLine($"{i}");
action();
i = 666;
action(); // https://csharp.2000things.com/2014/09/09/1178-captured-variables-are-evaluted-when-a-delegate-is-invoked/
}
// https://csharp.2000things.com/2014/09/19/1186-capturing-a-foreach-iteration-variable-in-a-lambda-expression/
private static void Test2()
{
const int length = 10;
Console.Write("1: ");
foreach (var i in Enumerable.Range(0, length))
Console.Write($"{i} ");
Console.WriteLine();
Console.Write("2: ");
foreach (var i in Enumerable.Range(0, length))
{
Action action = () => Console.Write($"{i} ");
action();
}
Console.WriteLine();
Console.Write("3: ");
var actions = new Action[length];
foreach (var i in Enumerable.Range(0, length))
actions[i] = () => Console.Write($"{i} ");
foreach (var action in actions)
action();
Console.WriteLine();
Console.Write("4: ");
var actions2 = new Action[length];
foreach (var i in Enumerable.Range(0, length))
{
var index = i;
actions2[i] = () => Console.Write($"{index} ");
}
foreach (var action in actions2)
action();
Console.WriteLine();
}
// https://csharp.2000things.com/2014/09/15/1182-capturing-a-for-loop-variable-in-a-lambda-expression/
private static void Test3()
{
const int length = 10;
Console.Write("1: ");
for (var i = 0; i < length; i++)
Console.Write($"{i} ");
Console.WriteLine();
Console.Write("2: ");
for (var i = 0; i < length; i++)
{
Action action = () => Console.Write($"{i} ");
action();
}
Console.WriteLine();
Console.Write("3: ");
var actions = new Action[length];
for (var i = 0; i < length; i++)
actions[i] = () => Console.Write($"{i} ");
foreach (var action in actions)
action();
Console.WriteLine();
Console.Write("4: ");
var actions2 = new Action[length];
for (var i = 0; i < length; i++)
{
var index = i;
actions2[i] = () => Console.Write($"{index} ");
}
foreach (var action in actions2)
action();
Console.WriteLine();
}
// Local Functions
private static void Test4()
{
const int length = 10;
Console.Write("1: ");
foreach (var i in Enumerable.Range(0, length))
Console.Write($"{i} ");
Console.WriteLine();
Console.Write("2: ");
foreach (var i in Enumerable.Range(0, length))
{
void write() => Console.Write($"{i} ");
write();
}
Console.WriteLine();
Console.Write("3: ");
var actions = new Action[length];
foreach (var i in Enumerable.Range(0, length))
{
void write() => Console.Write($"{i} ");
actions[i] = write;
}
foreach (var action in actions)
action();
Console.WriteLine();
Console.Write("4: ");
var actions2 = new Action[length];
foreach (var i in Enumerable.Range(0, length))
{
var index = i; // Roslyn tells us this is useless and indeed it is!
void write() => Console.Write($"{index} ");
actions2[i] = write;
}
foreach (var action in actions2)
action();
Console.WriteLine();
}
// Local Functions
private static void Test5()
{
const int length = 10;
Console.Write("1: ");
for (var i = 0; i < length; i++)
Console.Write($"{i} ");
Console.WriteLine();
Console.Write("2: ");
for (var i = 0; i < length; i++)
{
void write() => Console.Write($"{i} ");
write();
}
Console.WriteLine();
Console.Write("3: ");
var actions = new Action[length];
for (var i = 0; i < length; i++)
{
void write() => Console.Write($"{i} ");
actions[i] = write;
}
foreach (var action in actions)
action();
Console.WriteLine();
Console.Write("4: ");
var actions2 = new Action[length];
for (var i = 0; i < length; i++)
{
var index = i; // Roslyn tells us this is useless, but IT IS NOT!!!
void write() => Console.Write($"{index} ");
actions2[i] = write;
}
foreach (var action in actions2)
action();
Console.WriteLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment