Je me demandais si quelqu'un pouvait expliquer ce que Func<int, string>
is et comment il est utilisé avec quelques exemples clairs.
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
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. :)
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();
}
}
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