Click here to Skip to main content
15,887,214 members
Articles / Programming Languages / C# 4.0

Welcome Microsoft Delegate! Lambda Expressions Right this Way…

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
2 Apr 2011CPOL2 min read 7.2K   6  
Welcome Microsoft Delegate! Lambda Expressions right this way…

Delegates are deceptively great. Without them, something as simple as the OnClick event of a button would cease to work. In a nutshell, they offer a simple way to pass a function as a parameter which in turn can be invoked anywhere, anytime. Pointers for functions, very useful!

In .NET v2.0, the anonymous delegate was quietly introduced, well at least it slipped my notice. I read about them at the same time I read about Lambda functions. I saw them laid bare without the syntactic sugar in all their simple glory. As I was stuck on a .NET v2.0 project, I found sugar-free anonymous delegates useful to, say, recursively find all controls of a given Type and execute a function on the matching controls.

More recently, I was working on a robust Windows service responsible for various IO operations. It was vitally important each file operation (heretofore fileop) had its own comprehensive try/catch block. As the number of fileops increased, the code looked like one huge catch block.

It was clear it would be nice to have just one try/catch block in a static utility class which could catch every IO exception conceivable. Then, I could replace each try/catch block with one-line:

JavaScript
bool isBackedUp = FileUtil.FileOp(_logger, () => File.Copy(latestFilename, 
   backupFilename, true));

Notice the file copy on the other side of the lambda function syntax, () =>, is what is executed in the try block below:

JavaScript
public delegate void FileOperation();
internal static bool FileOp(ILogger logger, FileOperation fileOp)
{
bool success = false;
try
{
fileOp.DynamicInvoke();
success = true;
}
catch (ArgumentException argEx)
{
logger.Error(argEx, "Bad arguement(s) passed");
}
catch (DirectoryNotFoundException dirEx)
{
logger.Error(dirEx, "The specified path is invalid");
}
catch (FileNotFoundException fileEx)
{
logger.Error(fileEx, "The specified file was not found");
}
catch (PathTooLongException pathEx)
{
logger.Error(pathEx, 
    "The specified path, file name, or both exceed the system-defined maximum length");
}
catch (IOException ioEx)
{
logger.Error(ioEx, "An I/O error has occurred");
}
catch (NotSupportedException supportEx)
{
logger.Error(supportEx, "The requested operation was not supported");
}
catch (SecurityException secEx)
{
logger.Error(secEx, "The caller does not have the required permission.");
}
catch (UnauthorizedAccessException accessEx)
{
logger.Error(accessEx, "The caller does not have the required permission");
}
catch (Exception ex)
{
logger.Error(ex, "General fileop exception");
}
return success;
}

Not only was this an elegant way to catch a comprehensive set of exceptions, but the resulting code was much more readable.

Of course, we could pass bigger chunks of code and this is fine in moderation. But the flip-side can mean less readable code when lambda functions (and especially lambda expressions) are used without restraint. Readability for the whole team is paramount. After all, too much syntactic sugar will rot your teeth!

The brilliant thing about C# is the mind set of “I’m sure there’s a way to do this” is often rewarded with a little research.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Avaya Inc.
Ireland Ireland
Formerly a C++ client developer, nowadays I'm all about C# and ASP.NET. Over the years I have mastered some and played with many aspects of .NET.

Follow my blog as I catalogue the more arcane problems I encounter and their solutions at CodingLifestyle.com

Comments and Discussions

 
-- There are no messages in this forum --