Wednesday 17 October 2012

C# Anonymous functions, Lambda Expressions and Closures


In this post, we’ll explore ways to make method declaration more flexible.
 

Overview
  • Delegates
  • Lambda Expressions
  • Closures


A closer look at delegates
Delegates in .NET are used as a mechanism to contain methods in flexible variables or even specify them inline. This allows for additional implementation capabilities. Some more reading on delegates…
 

Some sections to consider before continuing:
(A) Delegate variable, (B) Named method, (C) Delegate assignment and (D) Initialization

  • Initialization using a named method
The original mechanism for implementing Delegates (Requires: A, B, C and D)



  • Inline anonymous method declaration
Anonymous functions are functions that has no name, as the logic is declared inline there is no need for a method name. Inline delegate declaration was added in .NET 2.0. (Requires: A, C and D)
 


  • Generic anonymous inline delegate implementation
In .Net 3.5 delegates usability was extended with the assistance of generics to allowing this shortened combination. Read some more on .Net delegate evolution (Requires: C and D)

  • Delegates as events
Events are just methods that require a specific structure (check this with system events for the same action). In general evenings are also linked to an action as a list of events.
    • Assign named event method using EventHandler (Win Forms):
Here we are using the generic delegate EventHandler (You can also create your own) to attach a named event method to a button click.



    • Adding an anonymous inline delegate method (Win Forms)

Lambda Expressions


  • Basic inline lambda expressions

  • Explicit inline Lambda expression
Take note of the explicitly defined parameter type and return statement. More examples...


  • Here is the same method but implicitly defined
  • Iterating through generic List using Lambda expression
  • Generic list manipulation



Closures
As delegate placeholders can be assigned from logic (opposed to being defined strictly in structure) it also provides opportunities to define relationships between object methods and other objects.

Key to this approach is the context in which the assigned delegate is executed. It is not from the object that defined the placeholder delegate (Children) but rather, in case of a named method delegate reference, the object that contains the named method declaration (Parent).

Why is this significant?
  • Executes a level higher than itself, this opens great potencial for siblings actions to affect each other and global attributes of their parent.
  •  Because the delegates are assigned not defined in a set structure you can assign different methods to the same delegate placeholder.
E.g. here we have a math university class that requires a global average property to be kept up to date every time a student average changes.


  • Create the parent object (MathClass)

  •  Create the child object (Student)
  •  Create a method to populate our class with test data
  • At this point we just need run a test on how changes in Student affects the class average

You can download the source code for this post from GitHub.

Note: It does not include the WinForm example and the startup class needs to change to switch between examples.