Pergunta
Eu queria saber se alguém poderia explicar o que Func<int, string>
é e como ele é usado com alguns exemplos claros.
Solução
Você está familiarizado com os delegados em geral? Eu tenho uma página sobre delegados e eventos que podem ajudar se não, embora seja mais orientada para explicar as diferenças entre os dois.
Func<T, TResult>
é apenas um delegado genérico - trabalho para fora o que significa em qualquer situação particular, substituindo o parâmetros de tipo (T
e TResult
) com o correspondente argumentos de tipo (int
e string
) na declaração. Eu também renomeou para confusão evitar:
string ExpandedFunc(int x)
Em outras palavras, Func<int, string>
é um delegado que representa uma função de tomar um argumento int
e retornando um string
.
Func<T, TResult>
é utilizado frequentemente em LINQ, tanto para as projecções e predicados (no último caso, é sempre TResult
bool
). Por exemplo, você poderia usar um Func<int, string>
para projetar uma seqüência de números inteiros em uma seqüência de strings. As expressões lambda são geralmente usados ??em LINQ para criar os delegados relevantes:
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);
}
Resultado:
Value=3
Value=7
Value=10
Outras dicas
come Func<int, string>
ints e retorna cordas. Então, o que come ints e retorna cordas? Como sobre isto ...
public string IntAsString( int i )
{
return i.ToString();
}
Não, eu acabei de inventar uma função que come ints e retorna strings. Como eu iria usá-lo?
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"
Não é muito sexy, eu sei, mas essa é a idéia simples de que um monte de truques são baseadas. Agora, vamos usar um Func vez.
Func<int, string> fnc = IntAsString;
foreach (int i in lst)
{
str += fnc(i);
}
// str will be "1234512345" assuming we have same str as before
Em vez de chamar IntAsString em cada membro, eu criei uma referência a ele chamou FNC (estas referências a métodos são chamados delegados ) e usado em vez disso. (Lembre-se come FNC ints e retorna cordas).
Este exemplo não é muito sexy, mas uma tonelada do material inteligente que você vai ver é baseado na ideia simples de funções, os delegados e métodos de extensão .
Uma das melhores primers sobre essas coisas que eu vi é aqui . Ele tem um monte exemplos mais reais. :)
É um delegado que leva um int
como um parâmetro e retorna um valor do tipo string
.
Aqui está um exemplo de seu uso:
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>
aceita um parâmetro de valor int e retorna um valor string. Aqui está um exemplo onde um método de apoio adicional é desnecessária.
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);
NOTA: O último tipo de objeto em Func (ou seja, "string" neste exemplo) é as funções tipo de retorno (ou seja, não se limitando a primitivas, mas qualquer objeto). Portanto, Func<int, bool, float>
aceita parâmetros int e valor booleano e retorna um valor flutuante.
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