Something I’ve struggled with in the past with C# is anonymous functions. Its one of those “how can you call yourself a professional if you don’t understand this?” kind of things.

Conceptually, I understand them. Its a function, without a name. But actually implementing with them has been a struggle that I usually end up going around. Something about saying x => x.doSomeStuff() inside the arguments to another function. What is x, how does the compiler know, wtf? This is particuarly uneasing because I used them all the time in ASP.NET views. Here’s one of the signatures for Html.TextBoxFor():

TextBoxFor<TModel, TProperty>(HtmlHelper<TModel>, Expression<Func<TModel, TProperty>>, IDictionary<String, Object>)

Expression<Func<TModel, TProperty>>… huuuuuuuuh?

But not today. Today I figured it out.

The problem was simple: validate a string before passing it off to another system. The string has to be only letters, numbers, or spaces.

The first version was without spaces but then I found out I needed to handle spaces. This was easy to do with the help of intellisense, I did it without really getting what was going on. if(! filterThisString.All(c => char.IsLetterOrDigit(c)))

Then I had to add the filter for spaces, and I tried too hard. Exactly none of this code made any sense and the compiler was happy to inform me of such. if(! filterThisString.All(new Func<char,bool> => () char.IsLetterOrDigit || char.Equals(' ')

So then I figured that if I wanted to write my own func I was just going to have to declare it outside of the function.

Func<char, bool> isValidCharacter = c => char.IsLetterOrDigit(c) || c.Equals(' ');
if(! filterThisString.All(isValidCharacter))

That works, yay! I wrote a Func, but its not anonymous. It has a name.

Then the ‘aha’ moment came when I took another stab at one-lining it. I don’t need any of the signature when using an anonymous function. The compiler figures it out for you! That’s why you just need to declare a reference to what you want to manipulate. Now it all clicks.

if(! filterThisString.All(c => char.IsLetterOrDigit(c) || c.Equals(' ')))