Share via

Func<T> VS Action<T>

Pip 265 Reputation points
2026-02-27T05:30:58.0766667+00:00

Hi ,

I'm using .NET 10 and Visual Studio 2026.

Can you please tell me how to use both Func<T> and Action<T> ?

When to use each one ?

I see it very common used to pass it as a parameters to function.

Can yo please demonstrate this usage and the meaning ?

Thanks,

Developer technologies | C#
Developer technologies | C#

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.

0 comments No comments
{count} votes

Answer accepted by question author
  1. Jack Dang (WICLOUD CORPORATION) 14,960 Reputation points Microsoft External Staff Moderator
    2026-02-27T06:21:43.4633333+00:00

    Hi @Pip ,

    Thanks for reaching out.

    Both Func<T> and Action<T> are delegates, think of them as variables that can hold methods you can run later. The difference is simple but important:

    • Action<T> - takes input, does something, returns nothing.
    • Func<T> - takes input, does something, returns a value.

    So the choice depends on whether you need a result back or not.

    Here’s a quick example to illustrate:

    // Action example: performs work but returns nothing
    void Greet(string name, Action<string> action)
    {
        action(name);
    }
    
    Greet("John", n => Console.WriteLine($"Hello {n}"));
    // Output: Hello John
    
    // Func example: performs work and returns a value
    int Compute(int x, Func<int, int> operation)
    {
        return operation(x);
    }
    
    int result = Compute(5, n => n * n);
    Console.WriteLine(result); // Output: 25
    

    In practice, you often pass Func or Action as parameters to methods when you want flexible behavior. Instead of hardcoding what a method does, you let the caller decide.

    Hope this helps clarify things and gives you a clear idea of when and how to use each! If my answer was helpful - kindly follow the instructions here so others with the same problem can benefit as well.

    2 people found this answer helpful.

Answer accepted by question author
  1. Q&A Assist
    2026-02-27T05:31:16.1066667+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    Func<T> and Action<T> are predefined delegate types used to pass methods (including lambdas) as parameters.

    Summary:

    • Func<...>: method returns a value.
    • Action<...>: method does not return a value (void).

    Both can have 0–16 input parameters:

    • Func<TResult> up to Func<T1,...,T16,TResult>
    • Action up to Action<T1,...,T16>

    The last type parameter of Func is always the return type.

    When to use each

    Use Action<...> when:

    • The method performs an operation and does not need to return anything.
    • Example: logging, writing to console, updating a collection, sending a message.

    Use Func<...> when:

    • The method computes and returns a result from its inputs.
    • Example: projections, calculations, predicates, transformations.

    From the documentation:

    • Action<> is used when there is a need to perform an action using the arguments of the delegate. The method it encapsulates does not return a value.
    • Func<> is used when a transformation is needed; the method it encapsulates returns a specified value.

    Basic examples

    Func examples

    A Func<string, int> that takes a string and returns its length:

    Func<string, int> getLength = s => s.Length;
    
    int len = getLength("hello"); // len == 5
    

    A Func<string, int, bool> that checks if the string length equals a given number (from the docs):

    Func<string, int, bool> predicate = (str, index) => str.Length == index;
    
    string[] words = { "orange", "apple", "Article", "elephant", "star", "and" };
    IEnumerable<string> aWords = words.Where(predicate).Select(str => str);
    
    foreach (string word in aWords)
        Console.WriteLine(word);
    

    Here:

    • Parameters: string and int.
    • Return type: bool (TResult).
    • Used as a parameter to Where, which expects a Func<...>.

    Another example using a named method instead of a lambda (from the docs):

    Func<string, int, string[]> extractMethod = ExtractWords;
    
    string title = "The Scarlet Letter";
    foreach (string word in extractMethod(title, 5))
        Console.WriteLine(word);
    
    string[] ExtractWords(string phrase, int limit)
    {
        char[] delimiters = { ' ' };
        return limit > 0 ? phrase.Split(delimiters, limit) : phrase.Split(delimiters);
    }
    

    Action examples

    Action<string, string> that writes two strings to the console (from the docs):

    Action<string, string> concat = WriteToConsole;
    
    concat("The first line of a message.", "The second line of a message.");
    
    void WriteToConsole(string string1, string string2)
    {
        Console.WriteLine("{0}\n{1}", string1, string2);
    }
    

    Same example using a lambda instead of a named method:

    Action<string, string> concat = (s1, s2) =>
    {
        Console.WriteLine("{0}\n{1}", s1, s2);
    };
    
    concat("The first line of a message.", "The second line of a message.");
    

    Action<string[], string[], int> that copies part of one array to another (from the docs):

    Action<string[], string[], int> copyOperation = CopyStrings;
    
    copyOperation(ordinals, copiedOrdinals, 3);
    
    void CopyStrings(string[] source, string[] target, int startPos)
    {
        if (source.Length != target.Length)
            throw new IndexOutOfRangeException("The source and target arrays must have the same number of elements.");
    
        for (int ctr = startPos; ctr <= source.Length - 1; ctr++)
            target[ctr] = source[ctr];
    }
    

    Passing Func and Action as parameters

    A method that takes a Func<int, int> and applies it:

    static int ApplyTwice(int value, Func<int, int> operation)
    {
        return operation(operation(value));
    }
    
    int result = ApplyTwice(3, x => x * 2); // (3 * 2) * 2 = 12
    

    A method that takes an Action<string> and calls it:

    static void NotifyUsers(IEnumerable<string> users, Action<string> notifier)
    {
        foreach (var user in users)
            notifier(user);
    }
    
    NotifyUsers(new[] { "Alice", "Bob" }, name => Console.WriteLine($"Hello, {name}"));
    

    Func vs Action in LINQ and TPL/PLINQ

    Many .NET APIs accept Func/Action parameters, especially LINQ and TPL/PLINQ:

    • LINQ operators like Where, Select use Func delegates (they need to return a value, e.g., bool for filtering, a projection type for Select).
    • TPL methods like Parallel.ForEach often use Action when they just perform work on each element, and Func when they compute and return local state.

    From the TPL/PLINQ documentation:

    • The underlying type of a lambda expression is one of the generic Func delegates, which makes it possible to pass a lambda expression as a parameter without explicitly assigning it to a delegate.
    • Action delegates encapsulate methods that do not return a value; type parameters represent only input parameters.

    Rule of thumb

    • If the delegate’s method returns something → use Func<...> (last type is the return type).
    • If the delegate’s method returns nothing (void) → use Action<...>.

    Func and Action avoid declaring custom delegate types and are the standard way to pass behavior (methods, lambdas) into APIs in modern .NET.


    References:


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.