Introduction

In general, we can say Func is a special function which holds/handles many arguments. In other words, we can say they handle delegates, anonymous or generic types as a parameter. It encapsulates a method which can accept parameterized types.

The type of Func is a parameterized type. It can handle an anonymous method in a simpler way.

A typical syntax for Func is:

Func<T, TResult>

Referring to MSDN: http://msdn.microsoft.com/en-us/library/bb549151%28v=vs.110%29.aspx

Func is a part of System namespace and is defined as:

public delegate  TResult Func<in  T, out  TResult>(T arg)

Where: 

in T: Type of the parameter of the method to encapsulate

out TResult: Type of the return value of the method

Let's think of some scenarios where someone wants to

  •  Format a number
  •  Make text upper case

Nowadays, we have many options to do this. We can choose in-built methods/functions or we can define own methods/functions, especially when we are delivering some kind of finished product to external users. These type of users would not be aware and do not want to know the internal functionality but they want an accurate result.

So, let's define our own methods in a simpler way:

Work without Func

Define an Interface:IWithoutFuncType

namespace MyStuff
{
 public interface IWithoutFuncType
 {
 string ToUpper(string textToUpper);
 string FormatMe(int num);
 string ToSum(int num1, int num2);
 }
}

Implement interface: IWithoutFuncType to class WithoutFuncType

using System;
using System.Globalization;
namespace MyStuff
{
 public class WithoutFuncType : IWithoutFuncType
 {
 public string ToUpper(string textToUpper)
 {
 return textToUpper.ToUpper(CultureInfo.InvariantCulture);
 }
 public string FormatMe(int num)
 {
 return String.Format("You entered {0}.", num);
 
}
 public string ToSum(int  num1, int  num2)
 {
 return string.Format("Sum of {0} and {1} = {2}", num1, num2, num1 + num2);
 }
 }

Compile above class and run in console

The output of above is very obvious and you will get things as defined. From here, our need to Func exists. Above is a very simple example. There might be situations where we need to handle typical complex data and conditions for that do you want to write hundreds of  lines to just get a sum of two numbers or make it UpperCase? 

Frankly, we hate to write a method which would have more than - lines...

We can define the following Func types for our basic operations. Look at following snippet:

Func<string, string> _toUpper = st => st.ToUpper(CultureInfo.InvariantCulture);
Func<int, string> _formatMe = n => string.Format("You entered {0}", n);
Func<int, int, string> _toSum = (n, m) => string.Format("Sum of {0} and {1} = {2}", n, m, n + m);

Isn't it so simple, looks like one-liner and these methods defined themselves by their names? Let's take first _toUpper Func, it is accepting a string as a parameter and returning string as a result and name is toUpper which says "supply me any string and we will return a string in UpperCase".

Also, to use above Func you just need to call its Invoke() method with desired parameters to fire/trigger. See below snippet:

Console.WriteLine(_toUpper.Invoke(109));

Work without func

Let's think more complex areas you want performance and need to write a clean code. Due to the scope of this article, we are not going to define more live examples. Here is a complete snippet defining Func with typical usages:

Define an interface IWithFuncType

namespace MyStuff
{
 public interface  IWithFuncType
 {
 string FormatNumberAndMakeToUpper(int num);
 string GiveMeSumInDefinedFormat(int num1, int num2);
 string MakeMeInUpperCase(string stringToUpper);
 List<string> GiveMeFullNames(IEnumerable<FullName> suppliedNames);
 }
}

Implement interface IWithFuncType with class WithFuncType

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace MyStuff
{
 public class  WithFuncType : IWithFuncType
 {
 readonly Func<string, string> _toUpper = st => st.ToUpper(CultureInfo.InvariantCulture);
 readonly Func<int, string> _formatMe = n => string.Format("You entered {0}", n);
 readonly Func<int, int, string> _toSum = (n, m) => string.Format("Sum of {0} and {1} = {2}", n, m, n + m);
 public string  FormatNumberAndMakeToUpper(int num)
 {
 return MakeMeInUpperCase(_formatMe.Invoke(num));
 }
 public string  GiveMeSumInDefinedFormat(int num1, int num2)
 {
 return _toSum.Invoke(num1, num2);
 }
 public string  MakeMeInUpperCase(string stringToUpper)
 {
 return _toUpper.Invoke(stringToUpper);
 }
 public List<string> GiveMeFullNames(IEnumerable<FullName> suppliedNames)
 {
 var fullNames = new  List<string>();
 fullNames.AddRange(suppliedNames.Select(fullName => fullName.ToString(NameFormatter)));
 return fullNames;
 }
 private string  NameFormatter(FullName stringToFormat)
 {
 var builder = new  StringBuilder();
 builder.AppendFormat("{0} {1} {2}", stringToFormat.FirstName,
 stringToFormat.IsMiddleNameSupplied ? stringToFormat.MiddleName : "-", stringToFormat.LastName);
 return builder.ToString();
 }
 }
 public class  FullName
 {
 public string  FirstName { get; set; }
 public string  MiddleName { get; set; }
 public string  LastName { get; set; }
 public bool  IsMiddleNameSupplied
 {
 get { return !string.IsNullOrEmpty(MiddleName); }
 }
 
public string  ToString(Func<FullName, string> formatter)
 {
 return formatter(this);
 }
 }
}

Compile and run into Console

using System;
using System.Collections.Generic;
namespace MyStuff
{
 class Program
 {
 static void  Main(string[] args)
 {
 IWithFuncType withFuncType = new  WithFuncType();
 Console.WriteLine(withFuncType.MakeMeInUpperCase("this is with func type"));
 Console.WriteLine();
 Console.WriteLine(withFuncType.FormatNumberAndMakeToUpper(109));
 Console.WriteLine(withFuncType.GiveMeSumInDefinedFormat(101, 9));
 //This is a typical example to use of Func Type
 var fullName = GetSomeFullNames();
 var names = withFuncType.GiveMeFullNames(fullName);
 Console.WriteLine();
 Console.WriteLine("A typical use of Func Type");
 Console.WriteLine();
 foreach (var name in names)
 {
 Console.WriteLine("Full Name: {0}", name);
 }
 Console.ReadLine();
 }
 private static  void StuffWithFuncType()
 {
 IWithFuncType withFuncType = new  WithFuncType();
 Console.WriteLine(withFuncType.MakeMeInUpperCase("this is with func type"));
 Console.WriteLine();
 Console.WriteLine(withFuncType.FormatNumberAndMakeToUpper(109));
 Console.WriteLine(withFuncType.GiveMeSumInDefinedFormat(101, 9));
 //This is a typical example to use of Func Type
 var fullName = GetSomeFullNames();
 var names = withFuncType.GiveMeFullNames(fullName);
 Console.WriteLine();
 Console.WriteLine("A typical use of Func Type");
 Console.WriteLine();
 foreach (var name in names)
 {
 Console.WriteLine("Full Name: {0}", name);
 }
 }
 private static  List<FullName> GetSomeFullNames()
 {
 return new  List<FullName>
 {
 new FullName
 {
 FirstName = "Gaurav",
 MiddleName = "Kumar",
 LastName = "Arora"
 },
 new FullName
 {
 FirstName = "Joseph",
 MiddleName = "",
 LastName = "Bulger"
 },
 
new FullName
 {
 FirstName = "Shuby",
 MiddleName = "",
 LastName = "Arora"
 }
 };
 }
 }
}

In above, the user just needs to provide a list of FullName and the program will return complete name with the pre-defined format or business logic.

What to do next?

  1. You can download complete example of FuncType from GitHub: https://github.com/garora/somestuff 
  2. Refer to MSDN for more info: http://msdn.microsoft.com/en-us/library/bb549151%28v=vs.110%29.aspx