How do you use Func<> and Action<> when designing applications?

后端 未结 9 833
情书的邮戳
情书的邮戳 2020-12-22 16:27

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

相关标签:
9条回答
  • 2020-12-22 17:12

    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.

    0 讨论(0)
  • 2020-12-22 17:17

    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.

    0 讨论(0)
  • 2020-12-22 17:26

    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.

    0 讨论(0)
  • 2020-12-22 17:27

    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

    0 讨论(0)
  • 2020-12-22 17:29

    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));
      }
    }
    
    0 讨论(0)
  • 2020-12-22 17:29

    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;
    }
    
    0 讨论(0)
提交回复
热议问题