Blue Theme Orange Theme Green Theme Red Theme
 
DevExpress Free UI Controls
Home | Forums | Videos | Advertise | Certifications | Downloads | Blogs | Interviews | Jobs | Beginners | Training
 | Consulting  
Submit an Article Submit a Blog 
 Jump to
Skip Navigation Links
TechnologyExpand Technology
WebsiteExpand Website
Team Foundation Server Hosting
Search :       Advanced Search »
Home » Learn .NET » Lambda, Lambda, Lambda - Uncovering the Mystery Behind Lambda Expressions

Lambda, Lambda, Lambda - Uncovering the Mystery Behind Lambda Expressions

Lambda Expressions are a powerful addition to C# Programming. This article attempts to describe lambda expressions in simple terms to pave the way for some powerful uses of this construct.

Author Rank :
Page Views : 5848
Downloads : 41
Rating :
 Rate it
Level : Beginner
   Print Read/Post comments Post a comment  Similar Articles  
   Email to a friend  Bookmark  Author's other articles  
Download Files:
lambdaquadratic.zip
 
 
Discover the top 5 tips for understanding .NET Interop
Become a Sponsor
 Tag Cloud
 Latest Jobs
More ... 
 Latest Interview Questions
More ... 



fig0.png

Introduction

At first glance, a lambda expression looks like something your professor may have written on the blackboard in calculus class, but in reality, it is "syntactic sugar" built into the C# language over delegates.  In this article, we will begin to explore the nuances of lambda expressions by seeing how they they relate to delegates and how they can be used to implement a popular mathematical formula, the quadratic equation.

What is a delegate?

A delegate is nothing more than a function pointer in C#.  Unlike the function that sits in your C# class,  a delegate can be passed around like any other variable or property.  Why would you want to pass around a function?  The advantage of passing around a function, is that you can dynamically have it execute wherever you want inside of your code.  Jeremy Miller just wrote a great article in MSDN (Oct 2009) on how you can use lamdbas (a.k.a. delegates)  for various tasks such as helping you reduce code duplication, passing expressions into filters, generating calls from a separate thread into your UI thread, and more.  Delegates have opened C# up to the world of functional programming, so we .NET programmers now have at our disposal the richness of object-oriented mechanisms along with the power of functional constructs.

Delegates describe the signature of the function you want to pass around your program.  In the case of the quadratic formula, we need to pass in 3 parameters to produce our resulting roots. The delegate for a quadratic looks something like this:

delegate double QuadraticDelegate(double a, double b, double c);

Note that the delegate differs from an actual function in that you need to "new up" a delegate instance and give it a function.  The function can either take the form of an existing method in your class, or it can be an anonymous method.   An anonymous method defines the delegate without requiring an existing method.  In an anonymous method, you simply define the implementation when you are constructing the delegate instance.

In our first attempt at implementing the quadratic formula, we use 3 anonymous methods.  The first anonymous method calculates the discriminant of the quadratic formula.  The discriminant is then used by the quadratic formula anonymous methods to calculate the two roots of the equation.  Note that none of the delegates actually implement the formula, they just create the implementations needed to run against parameters a,b, and c.  Implementing the delegate is performed the same way you would call any other method, by passing values to the delegate.

Listing 1 - Implementing the quadratic formula with anonymous methods

delegate double QuadraticDelegate(double a, double b, double c);
static void Method1()
{
 
  Console.WriteLine("Method #1");

// create an anonymous method to calculate the discriminant
 
  QuadraticDelegate discriminant = delegate(double a, double b, double c) {return (b * b - 4d * a * c);};

// create an anonymous method for the quadratic functions
  
QuadraticDelegate quadratic1 = delegate(double a, double b, double c) { return (-b + Math.Sqrt(discriminant(a, b, c))) / (2 * a); };
   QuadraticDelegate quadratic2 = delegate(double a, double b, double c) { return (-b - Math.Sqrt(discriminant(a, b, c))) / (2 * a); };
// calculate the quadratic roots for x^2 + 5x + 6 by implementic the delegates instances.
 
 double val1 = quadratic1(1d, 5d, 6d);
 
double val2 = quadratic2(1d, 5d, 6d);
   Console.WriteLine("Roots are {0}, {1}", val1, val2);
// calculate the quadratic roots for x^2 + 40x + 6
   
double val3 = quadratic1(1d, 40d, 6d);
   
double val4 = quadratic2(1d, 40d, 6d);

Console.WriteLine("Roots are {0}, {1}", val3, val4);
Console.ReadLine();
}

Using Lambda Expressions to Implement delegates

A lambda expression is a fancy way of writing anonymous methods.  First let's look at a simple lambda expression and understand what it does.
The expression 

       x => x + 1    can simply be redefined as the anonymous method   delegate(int x) { return (x + 1);}

of course,  for the lambda expression to be fully resolved, you would need to assign the lambda expression to the delegate it is implementing.

delegate int SumInt(int num);

SumInt result = x => x + 1;

otherwise we have no way of resolving whether  x is an integer, double, or other type.  There are a few ways you can write the lambda expression x => x + 1 as shown in listing 2 below, all are equivalent.

Listing 2 - Multiple ways to write the lambda expression x => x + 1

delegate int SumInt(int num);
static void LambdaSample()
{
 
  SumInt val1 = (x) => x + 1;
  
Console.WriteLine("val = {0}", val1(1));
  
Console.ReadLine();
  SumInt val2 = x => x + 1;
 
Console.WriteLine("val = {0}", val2(1));
 
Console.ReadLine();
 
SumInt val3 = (int x) => x + 1;
 
Console.WriteLine("val = {0}", val3(1));
 
Console.ReadLine();
}

 
So now how do we write our equivalent quadratic expressions using lambdas?  Since we are passing in three parameters (a,b,c),  we'll need to place this expression on the left side.  On the right side, we will place our quadratic expression utilizing these parameters.

QuadraticDelegate quadratic1 = (a, b, c) => (-b + Math.Sqrt(discriminant(a, b, c))) / (2 * a);

The code above is equivalent to our anonymous method below ,  but some might argue, a lot easier to read (at least for those professors teaching advanced calculus). 

   QuadraticDelegate quadratic1 = delegate(double a, double b, double c) { return (-b + Math.Sqrt(discriminant(a, b, c))) / (2 * a); };
 

The full equivalent quadratic example using lambdas is shown in listing 3

Listing 3 -  Implementing the quadratic equation using lambda expressions

delegate double QuadraticDelegate(double a, double b, double c);
static void Method2()
 {
   
Console.WriteLine("Method #2");

  
// create an anonymous delegate to calculate the discriminant using a lambda expression
  
QuadraticDelegate discriminant = (a, b, c) => (b * b - 4d * a * c);
 
// create an anonymous delegate for the quadratic functions using lambdas
   
QuadraticDelegate quadratic1 = (a, b, c) => (-b + Math.Sqrt(discriminant(a, b, c))) / (2 * a);
   
QuadraticDelegate quadratic2 = (a, b, c) => (-b - Math.Sqrt(discriminant(a, b, c))) / (2 * a);
// calculate the quadratic roots for x^2 + 5x + 6
   
double val1 = quadratic1(1d, 5d, 6d);
   
double val2 = quadratic2(1d, 5d, 6d);
   
Console.WriteLine("Roots are {0}, {1}", val1, val2);
  
// calculate the quadratic roots for x^2 + 40x + 6
  
double val3 = quadratic1(1d, 40d, 6d);
  
double val4 = quadratic2(1d, 40d, 6d);
 
Console.WriteLine("Roots are {0}, {1}", val3, val4);
 
Console.ReadLine();
}

If we now look at the quadratic using lambdas reinterpreted in redgate's reflector, it does in fact confirm that lambdas are nothing more than anonymous delegates.  Our reflector code looks exactly like the code in Method1 shown in listing 1:

Listing 4 - Method Containing Lambda Expressions Reflected through RedGate's Reflector

fig3.png

Function Templates

 
It is sort of painful to have to declare the delegate and then assign it every time you need to use a lambda expression.  Microsoft has created these cool templates called Func that seem to generate the delegates for you.  We can therefore rewrite listing 3 as follows and avoid needing to create a quadratic delegate outside the method.

Listing 5 - Rewriting the quadratic implementation using the Func<T> delegate

static void Method3()
{
  
Console.WriteLine("Method #3");

 
// create an anonymous delegate to calculate the descriminant
   
Func<double, double, double, double> descriminant = (a, b, c) => (b * b - 4d * a * c);
 
// create an anonymous delegate for the quadratic functions
 
Func<double, double, double, double> quadratic1 = (a, b, c) => (-b + Math.Sqrt(descriminant(a, b, c))) / (2 * a);
 
Func<double, double, double, double> quadratic2 = (a, b, c) => (-b - Math.Sqrt(descriminant(a, b, c))) / (2 * a);

// calculate the quadratic roots for x^2 + 5x + 6
 
double val1 = quadratic1(1d, 5d, 6d);
 
double val2 = quadratic2(1d, 5d, 6d);
 
Console.WriteLine("Roots are {0}, {1}", val1, val2);
// calculate the quadratic roots for x^2 + 40x + 6
  
double val3 = quadratic1(1d, 40d, 6d);
  
double val4 = quadratic2(1d, 40d, 6d);
 
Console.WriteLine("Roots are {0}, {1}", val3, val4);
 
Console.ReadLine();
}


The first 3 double parameters in the Func template are for the 3 doubles passed into the function.  The last double parameter is the return value type.  Microsoft would have had to create a different Func template for varying number of parameters, so I was curious at what point they stopped creating Func<T> methods.  After all there could be an infinite number of Func<T1, T2, T3, T4, T5, ...Result>.  The MSDN documentation and intellisense shows a maximum of 4, so I guess my sample came close to hitting the limit.  Anyway, below are the results of all three methods of producing the quadratic, and as expected all produce equivalent results .

fig1.png
Figure 1 - Results of running all three delegate methods

Conclusion 

This is just the tip of the iceberg of what you can do with lambda expressions, but hopefully this article helps clarify what a lambda expression is used for in C#.  Lambda expressions start to get more interesting when you start to take advantage of the closure principle or when you use lambdas with powerful technologies such as LINQ.  In the meantime, don't  be afraid to delegate your knowledge to your programming tasks and harness the power of lambda in C# and .NET.


Comment Request!
Thank you for reading this post. Please post your feedback, question, or comments about this post Here.
Login to add your contents and source code to this article
 [Top] Rate this article
 
 About the author
 
Mike Gold

Michael Gold is President of Microgold Software Inc., makers of the WithClass UML Tool. His company is a Microsoft VBA Partner and Borland Partner. Mike is a Microsoft MVP and founding member of C# Corner. He has a BSEE and MEng EE from Cornell University and has consulted for Chase Manhattan Bank, JP Morgan, Merrill Lynch, and Charles Schwab. Currently he is a senior developer at Finisar Corp. He has been involved in several .NET book projects, and is currently working on a book for using .NET with embedded systems.

He can be reached at mike@c-sharpcorner.com

Looking for C# Consulting?
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models.
Click here to learn more about C# Consulting.
 
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
Discover the Top 5 .NET Memory Management Fundamentals
To write the best .NET code, you need to know exactly how the .NET framework really manages memory. Ricky Leeks presents the Top 5 fundamental facts of .NET memory management. Learn more.
Nevron Chart for .NET 2010.1 Now Available
The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
ASP.NET 4 Hosting
Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites – Click Here!
 
 Post a Feedback, Comment, or Question about this article
Subject:
Comment:
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor
 Comments
thanks for the article by danny On November 3, 2009
I wonder... is it possible to use Func< ... > for making a function with no return value?


---------------------------------------------------
Danny,
Business loan, Unsecured loans and Fire Sprinklers
Reply | Email | Modify 
Re: thanks for the article by Ujwol On September 12, 2010
Action<> is what you are looking for..
Reply | Email | Modify 
Discover the top 5 tips for understanding .NET Interop
 © 2012  contents copyright of their authors. Rest everything copyright Mindcracker. All rights reserved.