ZetCode

C# Func

last modified October 6, 2020

C# Func tutorial shows how to use the Func delegate in C#.

C# does not have plain functions only member functions (aka methods). And the methods are not first-class citizens. First-class functions allow us to create beautiful and powerful code, as seen in F#. C# ameliorates this somewhat with the usage of delegates and lambda expressions. Func is a built-in delegate which brings some functional programming features and helps reduce code verbosity.

C# Func

Func is a built-in generic delegate type. Others include Predicate and Action. Func can be used with a method, an anonymous method or a lambda expression.

Func can contains 0 to 16 input parameters and must have one return type. (There are 16 overloads of the Func delegate.)

public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);

For instance, this delegate encapsulates a method that has two parameters and returns a value of the type specified by the TResult parameter.

C# Func simple example

The following example is a simple demonstration of a C# Func delegate.

Program.cs
using System;

namespace FuncSimple
{
    class Program
    {
        static string GetMessage()
        {
            return "Hello there!";
        }

        static void Main(string[] args)
        {
            Func<string> sayHello = GetMessage;
            Console.WriteLine(sayHello());
        }
    }
}

In the example, we use the Func delegate which has no parameters and returns a single value.

static string GetMessage()
{
    return "Hello there!";
}

This is the method to which we refer with the help of the Func delegate.

Func<string> sayHello = GetMessage;

We refer to the GetMessage method via the Func delegate. The Func helps us create concise code.

Console.WriteLine(sayHello());

We invoke the method through the delegate and print the output.

$ dotnet run
Hello there!

This is the output.

C# Func examples

The following example uses Func to add values.

Program.cs
using System;

namespace FuncEx
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<int, int, int> Add = Sum;

            int res = Add(150, 10);

            Console.WriteLine(res);
        }

        static int Sum(int x, int y)
        {
            return x + y;
        }
    }
}

We have a Sum method which adds two values. We refer to the method via the Func delegate.

Func<int, int, int> Add = Sum;

This Func delegate takes two parameters and returns a single value.

$ dotnet run
160

This is the output.

In the following example, we use a delegate with three input parameters.

Program.cs
using System;

namespace FuncEx
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<int, int, int, int> Add = Sum;

            int res = Add(150, 20, 30);

            Console.WriteLine(res);
        }

        static int Sum(int x, int y, int z)
        {
            return x + y + z;
        }
    }
}

This time we refer to a method which takes three parameters.

$ dotnet run
200 

This is the output.

Without the built-in Func delegate, we need to declare our custom delegate.

Program.cs
using System;

namespace FuncEx
{
    class Program
    {
        delegate int Add(int x, int y);

        static void Main(string[] args)
        {
            Add AddTwo = Sum;
            int res = AddTwo(150, 10);

            Console.WriteLine(res);
        }

        static int Sum(int x, int y)
        {
            return x + y;
        }
    }
}

In this example, we refer to Sum method via a custom delegate type.

C# Func with lambda expression

C# lambda expression simplifies the creation of C# Funcs. Lambda expressions are created with the => lambda declaration operator.

Program.cs
using System;

namespace FuncLambda
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<int, int, int> RandInt = (n1, n2) => new Random().Next(n1, n2);
            Console.WriteLine(RandInt(1, 100));
        }
    }
}

In the example, we create a function which returns a random integer. The delegate accepts two values for the lower and upper bounds of the random range.

C# Func Linq Where

Many Linq methods take Func delegates as parameters. For instance, the Where method filters a sequence of values based on a predicate.

Program.cs
using System;
using System.Collections.Generic;
using System.Linq;

namespace FuncWhere
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string, bool> HasThree = str => str.Length == 3;

            string[] words = 
            { 
                "sky", "forest", "wood", "cloud", "falcon", "owl" , "ocean", 
                "water", "bow", "tiny", "arc"
            };

            IEnumerable<string> threeLetterWords = words.Where(HasThree);

            foreach (var word in threeLetterWords)
            {
                Console.WriteLine(word);
            }
        }
    }
}

In the example, we have an array of words. With the help of the Func delegate, we filter all words that have three letters.

Func<string, bool> HasThree = str => str.Length == 3;

We declare a Func variable and assign a lambda expression to the variable. The method checks the length of the string and returns a boolean value.

IEnumerable<string> threeLetterWords = words.Where(HasThree);

We query the array and select strings according to the HasThree method.

$ dotnet run
sky
owl
bow
arc

This is the output.

C# Func filter list

In another example, we use a Func delegate to filter out a list of persons.

Program.cs
using System;
using System.Collections.Generic;
using System.Linq;

namespace FuncFilterList
{
    class Person
    {
        public string Name { get; set; }
        public string Occupation { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var data = new List<Person>
            {
                new Person() { Name = "John Doe", Occupation = "gardener" },
                new Person() { Name = "Robert Brown", Occupation = "programmer" },
                new Person() { Name = "Lucia Smith", Occupation = "teacher" },
                new Person() { Name = "Thomas Neuwirth", Occupation = "teacher" }
            };

            ShowOutput(data, r => r.Occupation == "teacher");

        }

        static void ShowOutput(List<Person> list, Func<Person, bool> condition)
        {
            var data = list.Where(condition);

            foreach (var person in data)
            {
                Console.WriteLine("{0}, {1}", person.Name, person.Occupation);
            }
        }
    }
}

The example creates a list of persons. The ShowOutput method takes a predicate as the second parameter. It returns all persons who are teachers.

static void ShowOutput(List<Person> list, Func<Person, bool> condition)

We are passing a Func to the ShowOutput method. Methods cannot be passed as function arguments, only delegates.

$ dotnet run
Lucia Smith, teacher
Thomas Neuwirth, teacher

This is the output.

In this tutorial, we have worked with C# Func delegate.

Visit C# tutorial or list all C# tutorials.