All the examples I can find about Func<> and Action<> are simple as in the one below where you see how they technically work but I would like to see them used in examples where they solve problems that previously could not be solved or could be solved only in a more complex way, i.e. I know how they work and I can see they are terse and powerful, so I want to understand them in a larger sense of what kinds of problems they solve and how I could use them in the design of applications.
In what ways (patterns) do you use Func<> and Action<> to solve real problems?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestFunc8282
{
class Program
{
static void Main(string[] args)
{
//func with delegate
Func<string, string> convert = delegate(string s)
{
return s.ToUpper();
};
//func with lambda
Func<string, string> convert2 = s => s.Substring(3, 10);
//action
Action<int,string> recordIt = (i,title) =>
{
Console.WriteLine("--- {0}:",title);
Console.WriteLine("Adding five to {0}:", i);
Console.WriteLine(i + 5);
};
Console.WriteLine(convert("This is the first test."));
Console.WriteLine(convert2("This is the second test."));
recordIt(5, "First one");
recordIt(3, "Second one");
Console.ReadLine();
}
}
}
By keeping them generic and supporting multiple arguments, it allows us to avoid having to create strong typed delegates or redundant delegates that do the same thing.
Actually, i found this at stackoverflow (at least - the idea):
I use the
Action
andFunc
delegates all the time. I typically declare them with lambda syntax to save space and use them primarily to reduce the size of large methods. As I review my method, sometimes code segments that are similar will stand out. In those cases, I wrap up the similar code segments intoAction
orFunc
. Using the delegate reduces redundant code, give a nice signature to the code segment and can easily be promoted to a method if need be.I used to write Delphi code and you could declare a function within a function. Action and Func accomplish this same behavior for me in c#.
Here's a sample of repositioning controls with a delegate:
They're also handy for refactoring switch statements.
Take the following (albeit simple) example:
With an Action delegate, you can refactor it as follows:
I use an Action to nicely encapsulate executing database operations in a transaction:
Now to execute in a transaction I simply do
The InTran class can reside in a common library, reducing duplication and provides a singe location for future functionality adjustments.
I have a separate form that accepts a generic Func or an Action in the constructor as well as some text. It executes the Func/Action on a separate thread while displaying some text in the form and showing an animation.
It's in my personal Util library, and I use it whenever I want to do a medium length operation and block the UI in a non-intrusive way.
I considered putting a progress bar on the form as well, so that it could perform longer running operations but I haven't really needed it to yet.