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
I use an Action to nicely encapsulate executing database operations in a transaction:
public class InTran
{
protected virtual string ConnString
{
get { return ConfigurationManager.AppSettings["YourDBConnString"]; }
}
public void Exec(Action<DBTransaction> a)
{
using (var dbTran = new DBTransaction(ConnString))
{
try
{
a(dbTran);
dbTran.Commit();
}
catch
{
dbTran.Rollback();
throw;
}
}
}
}
Now to execute in a transaction I simply do
new InTran().Exec(tran => ...some SQL operation...);
The InTran class can reside in a common library, reducing duplication and provides a singe location for future functionality adjustments.
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.
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.
Dunno if it's bad form to answer the same question twice or not, but to get some ideas for better uses of these types in general I suggest reading Jeremy Miller's MSDN article on Functional Programming:
Functional Programming for Everyday .NET Development
One thing I use it for is Caching of expensive method calls that never change given the same input:
public static Func<TArgument, TResult> Memoize<TArgument, TResult>(this Func<TArgument, TResult> f)
{
Dictionary<TArgument, TResult> values;
var methodDictionaries = new Dictionary<string, Dictionary<TArgument, TResult>>();
var name = f.Method.Name;
if (!methodDictionaries.TryGetValue(name, out values))
{
values = new Dictionary<TArgument, TResult>();
methodDictionaries.Add(name, values);
}
return a =>
{
TResult value;
if (!values.TryGetValue(a, out value))
{
value = f(a);
values.Add(a, value);
}
return value;
};
}
The default recursive fibonacci example:
class Foo
{
public Func<int,int> Fibonacci = (n) =>
{
return n > 1 ? Fibonacci(n-1) + Fibonacci(n-2) : n;
};
public Foo()
{
Fibonacci = Fibonacci.Memoize();
for (int i=0; i<50; i++)
Console.WriteLine(Fibonacci(i));
}
}
Actually, i found this at stackoverflow (at least - the idea):
public static T Get<T>
(string cacheKey, HttpContextBase context, Func<T> getItemCallback)
where T : class
{
T item = Get<T>(cacheKey, context);
if (item == null) {
item = getItemCallback();
context.Cache.Insert(cacheKey, item);
}
return item;
}