Can someone explain what the C# "Func<T,T>" does?
Asked Answered
S

8

39

I'm reading the Pro MVC 2 book, and there is an example of creating an extension method for the HtmlHelper class.

Here the code example:

public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfo pagingInfo, Func<int,string> pageUrl)
{
    //Magic here.
}

And here is an example usage:

[Test]
public void Can_Generate_Links_To_Other_Pages()
{
    //Arrange: We're going to extend the Html helper class.
    //It doesn't matter if the variable we use is null            
    HtmlHelper html = null;

    PagingInfo pagingInfo = PagingInfo(){
        CurrentPage = 2,
        TotalItems = 28,
        ItemsPerPage = 10
    };

    Func<int, String> pageUrl = i => "Page" + i;

    //Act: Here's how it should format the links.
    MvcHtmlString result = html.PageLinks(pagingInfo, pageUrl);

    //Assert:
    result.ToString().ShouldEqual(@"<a href=""Page1"">1</a><a href=""Page2"">2</a><a href=""Page3"">3</a>")           

}

Edit: Removed part that confused the point of this question.

The question is: Why is the example using Func? When should I use it? What is Func?

Thanks!

Suit answered 15/3, 2011 at 17:23 Comment(5)
Mainly, I'd like to know what the Func<int, String> pageUrl = i => "Page1" + i; line is doing.Suit
I don't understand. Func<T, T> has nothing to do with extension methods. What are you asking?Orangy
You mean the declaration of PageLinks? The first parameter is this, i.e. it is an extension method. That parameter gets bound to the html object in the call.Bezonian
NOTE: Please disregard the extension method bit, I wrote the wrong question. I mainly want to learn about what Func is, and why this example chose to use it. Also, when I should use it. I provided the example, only for context purposes.Suit
Note: The reference to extension methods is purely because in the MVC book Func is first used in the chapter which introduces them.Hacksaw
G
106

A Func<int, string> like

Func<int, String> pageUrl = i => "Page" + i;

is a delegate accepting int as its sole parameter and returning a string. In this example, it accepts an int parameter with name i and returns the string "Page" + i which just concatenates a standard string representation of i to the string "Page".

In general, Func<TSource, TResult> accepts one parameter that is of type TSource and returns a parameter of type TResult. For example,

Func<string, string> toUpper = s => s.ToUpper();

then you can say

string upper = toUpper("hello, world!");

or

Func<DateTime, int> month = d => d.Month;

so you can say

int m = month(new DateTime(3, 15, 2011));
Geologize answered 15/3, 2011 at 17:26 Comment(0)
O
13

Func<int, String> means a callback method that takes an int parameter and returns a String as the result.

The following expression, which is known as a lambda expression:

Func<int, String> pageUrl = i => "Page" + i;

expands to something like this:

Func<int, String> pageUrl = delegate(int i)
{
    return "Page" + i;
}
Orangy answered 15/3, 2011 at 17:25 Comment(0)
S
3

The Func<int, string> line that you are inquiring about is known as a lambda expression.

Func<int, String> pageUrl = i => "Page" + i;

This line can be described as a function that takes an int parameter (i) and returns a string "Page" + i;

It can be re-written as:

delegate(int i)
{
    return "Page" + i;
}
Schaub answered 15/3, 2011 at 17:26 Comment(1)
Is it possible to overload delegates, say if the input was a generic T where T : class?Relaxation
H
1

Because the PageLinks method is an Extension Method.

In extension method, the first parameter starts with this keyword to indicate that it is an Extension method on the type represented by the first parameter.

The Func<T1, T2> is a delegate which represents a transformation from type T1 to type T2. So basically, your PageLinks method will apply that transformation to int to produce a string.

Howbeit answered 15/3, 2011 at 17:25 Comment(2)
Ok - but what about the Func part?Suit
See my answer for link to Func.Itinerary
I
1

Func<T, TResult>: Encapsulates a method that has one parameter and returns a value of the type specified by the TResult parameter. See this page for more details and examples. :-)

Itinerary answered 15/3, 2011 at 17:27 Comment(0)
A
1

Have a blog post on this. Using Func you can resolve some of functional discrepancy. Read here.

Albacore answered 29/5, 2014 at 9:38 Comment(0)
K
0

I have implemented a where() extension method using Func please have a look...

public static IEnumerable<Tsource> Where<Tsource> ( this IEnumerable<Tsource> a , Func<Tsource , bool> Method )
{

    foreach ( var data in a )
    {
        //If the lambda Expression(delegate) returns "true" Then return the Data. (use 'yield' for deferred return)
        if ( Method.Invoke ( data ) )
        {
            yield return data;
        }
    }
}

You can use it like,

        foreach ( var item in Emps.Where ( e => e.Name == "Shiv" ).Select ( e1 => e1.Name ) )
        {
            Console.WriteLine ( item );
        }
Kermes answered 7/4, 2014 at 12:50 Comment(0)
S
0

Create your own

Func<int,string> myfunc; 

then right click Func to view definition. You will see it is a delegate underneith

public delegate TResult Func<in T, out TResult>(T arg);
Salpingitis answered 13/11, 2014 at 6:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.