ZetCode

C# Func

last modified November 2, 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;

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

Func<string> sayHello = GetMessage;
Console.WriteLine(sayHello());

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

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

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

Func<string> sayHello = GetMessage;

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

Console.WriteLine(sayHello());

We invoke the function 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;

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

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

int res = add(150, 10);

Console.WriteLine(res);

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;

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

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

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

Console.WriteLine(res);

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;

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

Add AddTwo = Sum;
int res = AddTwo(150, 10);

Console.WriteLine(res);

delegate int Add(int x, int 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;

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;

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;

var data = new List<Person>
{
    new Person("John Doe", "gardener"),
    new Person("Robert Brown", "programmer"),
    new Person("Lucia Smith", "teacher"),
    new Person("Thomas Neuwirth", "teacher")
};

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


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);
    }
}

record Person(string Name, string 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.

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.