I think you're confusing terms from different languages. You seem to be using "Functor" in the C++ or Java sense, e.g. see the wikipedia page. In C++, it's an object of a class that overloads the function-call operator, so it can be used as a function but with state.
This is logically the same thing as a delegate bound to an instance method in C# (or any .NET language).
There are three ways to write such a thing. First, you can write an ordinary method, and then assign the name of the method to a delegate variable.
void MyMethod() { Console.WriteLine("Hi!"); }
void Foo()
{
Action a = MyMethod;
a();
}
Second, you can use anonymous method syntax, introduced in C# 2.0:
void Foo()
{
Action a = delegate { Console.WriteLine("Hi!"); }
a();
}
Thirdly, you can use lambda syntax, introduced in C# 3.0:
void Foo()
{
Action a = () => Console.WriteLine("Hi!");
a();
}
The advantage of the last two is that the body of the method can read and write local variables in the containing method.
The advantage of lambda syntax over anon-methods are that it is more succinct and it does type inference on parameters.
Update: The advantage of anon-methods (delegate
keyword) over lambdas is that you can omit the parameters altogether if you don't need them:
// correct way using lambda
button.Click += (sender, eventArgs) => MessageBox.Show("Clicked!");
// compile error - wrong number of arguments
button.Click += () => MessageBox.Show("Clicked!");
// anon method, omitting arguments, works fine
button.Click += delegate { MessageBox.Show("Clicked!"); };
I know of only one situation where this is worth knowing, which is when initializing an event so that you don't have to check for null
before firing it:
event EventHandler Birthday = delegate { };
Avoids a lot of nonsense elsewhere.
Finally, you mention that there are four kinds of functor. In fact there are an infinity of possibly delegate types, although some authors may have their favourites and there obviously will be some common patterns. An Action
or Command
takes no parameters and returns void
, and a predicate takes an instance of some type and returns true
or false
.
In C# 3.0, you can whip up a delegate with up to four parameters of any types you like:
Func<string, int, double> f; // takes a string and an in, returns a double
Re: Updated Question
You ask (I think) if there are many use cases for lambdas. There are more than can possibly be listed!
You most often see them in the middle of larger expressions that operate on sequences (lists computed on-the-fly). Suppose I have a list of people, and I want a list of people exactly forty years old:
var exactlyForty = people.Where(person => person.Age == 40);
The Where
method is an extension method on the IEnumerable<T>
interface, where T
in this case is some kind of Person
class.
This is known in .NET as "Linq to Objects", but known elsewhere as pure functional programming on sequences or streams or "lazy" lists (all different names for the same thing).