Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Welcome Microsoft Delegate! Lambda Expressions Right this Way…

0.00/5 (No votes)
2 Apr 2011 1  
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:

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:

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here