web-dev-qa-db-fra.com

Explication de Func

Je me demandais si quelqu'un pouvait expliquer ce que Func<int, string> is et comment il est utilisé avec quelques exemples clairs.

87
zSynopsis

Connaissez-vous les délégués en général? J'ai une page sur délégués et événements qui peut aider sinon, bien qu'elle soit plus orientée vers l'explication des différences entre les deux.

Func<T, TResult> est juste un délégué générique - déterminez ce que cela signifie dans une situation particulière en remplaçant les paramètres de type (T et TResult) avec les arguments de type correspondants (int et string) dans la déclaration. Je l'ai également renommé pour éviter toute confusion:

string ExpandedFunc(int x)

En d'autres termes, Func<int, string> est un délégué qui représente une fonction prenant un argument int et retournant un string.

Func<T, TResult> est souvent utilisé dans LINQ, à la fois pour les projections et les prédicats (dans ce dernier cas, TResult est toujours bool). Par exemple, vous pouvez utiliser un Func<int, string> pour projeter une séquence d'entiers dans une séquence de chaînes. Les expressions Lambda sont généralement utilisées dans LINQ pour créer les délégués appropriés:

Func<int, string> projection = x => "Value=" + x;
int[] values = { 3, 7, 10 };
var strings = values.Select(projection);

foreach (string s in strings)
{
    Console.WriteLine(s);
}

Résultat:

Value=3
Value=7
Value=10
138
Jon Skeet

UNE Func<int, string> mange des entiers et renvoie des chaînes. Alors, qu'est-ce qui mange des ints et renvoie des chaînes? Que dis-tu de ça ...

public string IntAsString( int i )
{
  return i.ToString();
}

Là, je viens de créer une fonction qui mange des entiers et renvoie des chaînes. Comment pourrais-je l'utiliser?

var lst = new List<int>() { 1, 2, 3, 4, 5 };
string str = String.Empty;

foreach( int i in lst )
{
  str += IntAsString(i);
}

// str will be "12345"

Pas très sexy, je sais, mais c'est l'idée simple sur laquelle beaucoup de tricks sont basés. Maintenant, utilisons plutôt un Func.

Func<int, string> fnc = IntAsString;

foreach (int i in lst)
{
  str += fnc(i);
}

// str will be "1234512345" assuming we have same str as before

Au lieu d'appeler IntAsString sur chaque membre, j'ai créé une référence appelée fnc (ces références aux méthodes s'appellent délégués ) et l'ai utilisée à la place. (N'oubliez pas que fnc mange des entiers et renvoie des chaînes).

Cet exemple n'est pas très sexy, mais une tonne de trucs intelligents que vous verrez est basé sur l'idée simple de fonctions, de délégués et de méthodes d'extension .

L'une des meilleures amorces sur ce genre de choses que j'ai vues est ici . Il a beaucoup plus d'exemples réels. :)

40
JP Alioto

Il s'agit d'un délégué qui prend un int comme paramètre et renvoie une valeur de type string.

Voici un exemple de son utilisation:

using System;

class Program
{
    static void Main()
    {
        Func<Int32, String> func = bar;

        // now I have a delegate which 
        // I can invoke or pass to other
        // methods.
        func(1);
    }

    static String bar(Int32 value)
    {
        return value.ToString();
    }
}
26
Andrew Hare

Func<int, string> accepte un paramètre de valeur int et renvoie une valeur de chaîne. Voici un exemple où une méthode de support supplémentaire n'est pas nécessaire.

Func<int, string> GetDogMessage = dogAge =>
        {
            if (dogAge < 3) return "You have a puppy!";
            if (dogAge < 7) return "Strong adult dog!";

            return "Age is catching up with the dog!";
        };

string youngDogMessage = GetDogMessage(2);

REMARQUE: Le dernier type d'objet dans Func (c'est-à-dire "chaîne" dans cet exemple) est le type de retour de fonctions (c'est-à-dire non limité aux primitives, mais à tout objet). Donc, Func<int, bool, float> accepte les paramètres de valeur int et bool et renvoie une valeur flottante.

Func<int, bool, float> WorthlessFunc = (intValue, boolValue) =>
        {
            if(intValue > 100 && boolValue) return 100;

            return 1;
        };
float willReturn1 = WorthlessFunc(21, false);
float willReturn100 = WorthlessFunc(1000, true);

HTH

1
jts