Je me demandais si quelqu'un pourrait expliquer ce que Func<int, string>
c'est et comment il est utilisé avec des exemples clairs.
Réponses:
Connaissez-vous les délégués en général? J'ai une page sur les délégués et les événements qui peuvent 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
) par 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 int
argument 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 a 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
A Func<int, string>
mange des entiers et renvoie des chaînes. Alors, qu'est-ce qui mange des entiers 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 ints et renvoie des chaînes. Comment l'utiliserais-je?
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 trucs sont basés. Maintenant, utilisons un Func à la place.
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 à celui-ci appelée fnc (ces références aux méthodes sont appelées 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 choses intelligentes que vous verrez est basée 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 truc que j'ai vues est ici . Il a beaucoup plus d'exemples réels. :)
C'est un délégué qui en 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 prise en charge 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 des fonctions (c'est-à-dire non limité aux primitives, mais à n'importe quel objet). Par conséquent, Func<int, bool, float>
accepte les paramètres de valeur int et booléenne 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