Quelqu'un peut-il expliquer ce que fait le C# "Func"?

Je lis le livre Pro MVC 2, et il y a un exemple de création d'une méthode d'extension pour la classe HtmlHelper.

Voici l'exemple de code:

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

Et voici un exemple d'utilisation:

[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: partie supprimée qui confondait le point de cette question.

La question est: pourquoi L'exemple utilise-t-il Func? Quand devrais-je utiliser? Qu'est-ce que Func?

Merci!

39
demandé sur jason 2011-03-15 20:23:06

8 réponses

Un Func<int, string> comme

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

Est un délégué acceptant int comme seul paramètre et renvoyant un string. Dans cet exemple, il accepte un paramètre int avec le nom i et renvoie la chaîne "Page" + i qui concatène simplement une représentation de chaîne standard de i à la chaîne "Page".

En général, Func<TSource, TResult> accepte un paramètre de type TSource et renvoie un paramètre de type TResult. Par exemple,

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

Alors vous pouvez dites

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

Ou

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

Donc vous pouvez dire

int m = month(new DateTime(3, 15, 2011));
105
répondu jason 2011-03-15 17:34:45

Func<int, String> signifie une méthode de rappel qui prend un paramètre int et renvoie un String comme résultat.

L'expression suivante, connue sous le nom d'expression lambda :

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

Se développe à quelque chose comme ceci:

Func<int, String> pageUrl = delegate(int i)
{
    return "Page" + i;
}
13
répondu BoltClock 2011-03-15 17:42:20

La ligne Func<int, string> que vous interrogez est connue comme une expression lambda.

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

Cette ligne peut être décrite comme une fonction qui prend un paramètre int (i) et renvoie une chaîne "Page" + i;

Il peut être réécrit comme:

delegate(int i)
{
    return "Page" + i;
}
3
répondu Kyle Trauberman 2011-03-15 17:34:51

Parce que la méthode PageLinks est une méthode D'Extension .

Dans méthode d'extension, le premier paramètre commence par ce mot clé pour indiquer qu'il s'agit d'une méthode D'Extension sur le type représenté par le premier paramètre.

Le Func<T1, T2> est un délégué qui représente une transformation de type T1 de type T2. Donc, fondamentalement, votre méthode PageLinks appliquera cette transformation à int pour produire un string.

1
répondu Unmesh Kondolikar 2011-03-15 17:31:37

Func<T, TResult>: encapsule une méthode qui a un paramètre et renvoie une valeur du type spécifié par le paramètre TResult. Voir cette page pour plus de détails, et des exemples. :-)

1
répondu Ke Sun 2011-03-15 17:41:45

Avoir un billet de blog à ce sujet. En utilisant Func, Vous pouvez résoudre certains écarts fonctionnels. Lire ici.

1
répondu nznoor 2014-05-29 09:38:14

J'ai implémenté une méthode d'extension where () en utilisant Func veuillez jeter un oeil...

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

Vous pouvez l'utiliser comme,

        foreach ( var item in Emps.Where ( e => e.Name == "Shiv" ).Select ( e1 => e1.Name ) )
        {
            Console.WriteLine ( item );
        }
0
répondu Sanu Uthaiah Bollera 2014-04-07 12:50:09

Créez votre propre

Func<int,string> myfunc; 

Puis cliquez avec le bouton droit sur Func pour afficher la définition. Vous verrez que c'est un délégué underneith

public delegate TResult Func<in T, out TResult>(T arg);
0
répondu timothy 2014-11-13 06:55:49