Language Enhancements Presentation Materials

by Chad 25. March 2009 18:25

I've uploaded the demo code and slides from my 'Language Enhancements That Make LINQ Possible' presentation at last night's Springfield .NET Users' Group meeting.  Thank you to everyone who attended; I enjoyed the questions and feedback. If you have any problems with the download or questions about the samples, leave me a message in the comments. Enjoy!

SGFUG_LanguageEnhancements.zip (70.19 kb)

Simplifying LINQ: Lambda Expressions

by Chad 21. March 2009 10:53

Using LINQ in your applications has a handful of prerequisites. A programmer confident with LINQ needs to understand Lambda Expressions, Anonymous Types, Extension Methods, Type Inference, Type Initialization, and most likely Expression Trees too.  While this seems like a long list, most of the items are things that you already know, but with a little twist. At the core of LINQ are lambda expressions. Lambda expressions are how you apply your business logic using LINQ constructs. Despite having a cool name, lambda expressions are little more than short-hand for defining a delegate.

Annotated LINQ to SQL Concepts

A delegate is a type that references a method.  Any method that matches the delegate's signature (return type and parameters) can be assigned to it.  Common uses for delegates are for sorting, filtering, or manipulating data. In the .NET framework, delegates are the basis for event handling and have been around since the Framework 1.0 days.  As the .NET Framework has evolved, delegates have remained fundamentally the same, but because of language enhancements and compiler magic the syntax has become something quite useful - Lambda Expressions.

 

Before .NET 2.0 Framework

In the beginning there were Named Methods. Using named methods required a decent amount of code. You had to first define the delegate:

public delegate bool IntFilter(int value);

Then write a method or methods that matched the delegate's signature.

public bool IsEven(int value)

{

    return (value % 2 == 0);

}

Then instantiate and use the delegate.

IntFilter filter = IsEven;

bool match = filter(1); // false

filter = IsOdd;

match = filter(1); // true

This example clearly illustrates the three steps for using delegates. 1.) Define a delegate. 2.) Define a method. 3.) Instantiate the delegate with your method. Where you'll see this most often is in event handling. Below, System.EventHandler is the Delegate and button1_Click is the named method that is assigned to instantiate the EventHandler.

button1.Click += new System.EventHandler(this.button1_Click);

private void button1_Click(object sender, EventArgs e)

{

    // Handle the button click

}

 

Enter the 2.0 Framework

When Microsoft released the .NET 2.0 Framework they introduced some compiler magic called anonymous methods. Anonymous methods allowed you to instantiate a delegate by defining your method inline. Anonymous methods reduce the extra coding effort of writing a separate method when there really isn't a need for it.  

IntFilter filter = delegate(int value) { return (value % 2 == 0); };

I say that this is compiler magic because if you look at your project in a tool like .NET Reflector, you'll see a method defined on your class similar to this.

[CompilerGenerated]

private static bool b__0(int value)

{

    return ((value % 2) == 0);

}

Some subtle but important rules apply to variable scoping in anonymous methods.  Parameters and variables defined within the anonymous method's code block are scoped to the code block. If a variable external to the code block is referenced from within the code block, it is said to be captured.  Captured variables will not be disposed of until the delegate goes out of scope. 

// threshold will NOT be garbage collected until f goes out of scope

int threshold = 5;

IntFilter f = delegate(int value) { return value < threshold; };

 

The 3.0 Framework introduces Lambda Expressions

Lambda Expressions use the lambda operator => (pronounced "goes to") to create delegates or expression trees. Think of them as shorthand for anonymous methods. The syntax is (parameters) => { statements; }. When only one parameter exists the parenthesis are optional. When more than one parameter exists they are separated by commas.

// Func<> and Action<> are two new Generic Delegates that support up to

// four input parameters. Func<> returns a value, Action<> does not.

Func<bool> noParams = () => { return true; };

Func<int, bool> oneParam = (int value) => { return value > 5; };

Func<int, int, bool> twoParams = (int value, int threshold) => { return value > threshold; };

 

  Statement Lambda Expression Lambda
Create Expression Trees No Yes
Instantiate Delegates Yes Yes

I digress...

There are actually two flavors of lambda expressions: Statement Lambdas and Expression Lambdas.  Statement lambdas use curly brackets and contain more than one statement. Expression lambdas do not use curly brackets and contain only one statement.  Statement lambdas cannot be used to create expression trees, expression lambdas can. Both can be used to instantiate delegates. This post discusses statement lambdas. 

Where lambda expressions really become useful is in LINQ.  LINQ provides a set of extension methods to the IEnumerable<> interface that can be used for sorting, filtering, and manipulating the contents of an IEnumerable<>. Below is a graphic with code examples of using the LINQ Where() extension method to filter an array of integers down to just the even integers.  I have highlighted the syntactical differences between using named methods, anonymous methods, and lambda expressions. Hopefully this helps illustrate the convenience that lambda expressions bring to the party and takes away some of the "magic" that can make learning lambda expressions confusing. The examples are ordered chronologically to show how the syntax has evolved to become more concise.

Delegate Syntax Comparisons

As always the best way to learn something is to play with it. To run these samples you'll need a project that targets the .NET 3.5 Framework and you'll need to add a using statement for the System.Linq (in System.Core.dll, Version 3.5) namespace.

Tags: ,

Simplifying-LINQ

SendTo Visual Studio as Administrator

by Chad 19. March 2009 05:11

I primarily develop in Virtual Machines, but lately I've been doing more work on my Vista boxes.  The biggest adjustment is that I can't double-click a .sln file anymore to launch Visual Studio.  A solution to this problem occurred to me the other day while working on something totally unrelated.

Why does this happen?

The reason that you can't double-click a solution file with UAC enabled is because the Visual Studio Version Selector won't pass elevated credentials along to Visual Studio when it launches. I could fix this by setting Visual Studio 2008 (as Admin) as the default program for .sln files, but I don't like that because I still have some Visual Studio 2005 solutions.

My workaround

Instead of opening the correct version of Visual Studio (as Admin) and using the Open File dialog box to navigate to my solution folder. I decided to create SendTo shortcuts for both versions of Visual Studio. 

  1. Open %APPDATA%\Microsoft\Windows\SendTo
  2. Right-click the folder > New > Shortcut
  3. Browse to the VS2008 .exe (mine was in "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe")
  4. Click Next
  5. Enter a name for the shortcut, this is what appears in the SendTo context menu (I entered "VS2008 as Admin")
  6. Click Next
  7. Right-click the new shortcut > Properties
  8. Select the Compatibility tab
  9. Check 'Run this program as an administrator'
  10. Click OK
Now you can right-click a .sln file > SentTo > VS2008 as Admin
 
You can do this same process for Visual Studio 2005 if you use it too, although if you use Visual Studio 2008 exclusively you may just want to change your default program. I hope this helps!

Tags: , ,

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

About the author

Chad

Meeeee!!!

Hi, my name is Chad Boschert and I'm a software developer in Springfield, Missouri. I've been developing .NET applications in C# since 2002.

Recent Comments

Comment RSS

Calendar

<<  February 2012  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
2728291234
567891011

View posts in large calendar