C# closure
last modified July 5, 2023
C# closure tutorial defines closures and shows how to use them.
A closure is an anonymous delegate which maintains access to free variables outside the definition of the block. It can still refer to the variables after the method has finished executing.
var limit = 0; Predicate<int> greaterThan = e => e > limit;
We have an anonymous lambda expression that refers to the limit
variable, even thought it vas not declared in the block or passed as a
parameter.
C# closure example
The following is a simple closure example.
var c = CreateCounter(); Console.WriteLine(c()); Console.WriteLine(c()); Console.WriteLine(c()); Console.WriteLine(c()); Console.WriteLine(c()); Func<int> CreateCounter() { int c = 0; return () => c = c + 1; }
The CreateCounter
is called several times; after each call, the
state (value of c
) is retained.
$ dotnet run 1 2 3 4 5
C# closure example II
Closures are often used in LINQ code.
var vals = new int[] {-1, -2, 0, 1, 5, 3}; var limit = 0; Func<int, bool> greaterThan = e => e > limit; var res = vals.Where(greaterThan); foreach (var e in res) { Console.WriteLine(e); }
In the example, we define a filter delegate. The limit
variable
that is used in the predicate is a free variable defined outside of the
predicate definition.
$ dotnet run 1 3 5
C# closure example III
We use a closure in the iterator example.
var words = new List<string> { "sky", "cloud", "rock", "war", "web" }; var it = CreateIterator(words); string e; while ((e = it()) != null) { Console.WriteLine(e); } Iterator<T> CreateIterator<T>(IList<T> data) where T : class { var i = 0; return delegate { return (i < data.Count) ? data[i++] : null; }; } public delegate T Iterator<T>() where T : class;
We have a generic iterator. In order for the iterator to work, we must retain the state of the increment variable.
Source
In this article we have worked with closures in C#.
Author
List all C# tutorials.