VB.NET: Where’s Action<T> support?
The release of a new version of .NET always provides an opportunity to shake our fists at the VB.NET language. Just when you thought the languages were finally equal, they’ve proven that once again VB.NET is a second class citizen in the country of .NET.
The C# 2.0 compiler introduced Anonymous Delegates. It allowed you to write code like this:
people.ForEach(delegate(Person p)
{
Console.WriteLine(p.Name);
});
In C# 3.0, lambda expressions were introduced, which also simplified the syntax for anonymous delegates:
people.Where(p => Console.WriteLine(p.Name));
Although VB.NET missed out on anonymous delegates, Lambda’s were too important to LINQ to let it slip, so they introduced this syntax:
people.Where(Function(p) Console.WriteLine(p.Name))
But here’s what they missed. The Where clause takes a Func<TArgument, bool> - that is, a delegate which takes a value and returns true or false. But not all code needs to return something. Take the ForEach operation again, which uses an Action<TArgument> as the input, which can also be expressed in C# with a lambda:
people.ForEach(p => Console.WriteLine(p.Name));
The compiler figures out that ForEach needs no return type, so the delegate it creates returns void.
They must have figured VB.NET programmers would never need to use this feature, so the Function(x) syntax doesn’t work for Action<T> - just Func’s.
I tried Sub(x), Call(x), Invoke(x), Do(x), Perform(x), Eval(x), Execute(x), Action(x), Expression(x), Lambda(x); but couldn’t find the equivalent for an Action<T>.
So what are we meant to do? I wrote a while back about "almost anonymous methods in VB.NET", which is what I’ll use in this case. It’s disappointing to see that VB.NET has come so far, and yet fallen short once again.
Filed under: VB.NET

Can’t get no VB Action ?
Paul Stovell finally notices the lack of support for statement lambdas in VB9 . Unfortunately Vb9 only
Amen Brother.
This issue has caused me nothing but heartache. It forces you to create a redundant Sub and use the ugly AddressOf syntax.
Hi Michael,
Yep. It’s OK if you don’t need access to any external local variables/arguments (like in my example above). It’s more work when you want to give a parameter to the method - you have to either make it a field, or create a wrapper class. In the end it’s easier to avoid the action in the first place.
I can’t see why they’d think this isn’t a useful feature.
Paul
Pfft, that’s the punishment you get for using VB.NET as your language instead of a real language like C#
/leaves before the fight breaks out
I agree, it’s one of the first things that I noticed and I was extremely disappointed.
They introduced great features that make it worthwhile to use VB (XML literals, Linq to XML syntax…), but this seemingly small difference makes it hell to create small event handlers (or deal with invokeRequired/Invoke pairs, for another useful example).
I don’t see why they couldn’t go all the way and use sub the way they used function (not that I particularly like this syntax but it would be consistent).
@Aaron - quite right!
@Dennis - yep!