Pregunta
Me preguntaba si alguien podría explicar por qué Func<int, string>
es y cómo se usa con algunos ejemplos claros.
Solución
¿Está familiarizado con los delegados en general? Tengo una página sobre que pueden ayudar si no, aunque es más orientado hacia rel="noreferrer"> explicar las diferencias entre los dos.
Func<T, TResult>
es sólo un delegado genérico - funcionó lo que significa en cualquier situación particular mediante la sustitución de la parámetros de tipo (T
y TResult
) con el correspondiente argumentos de tipo (int
y string
) en la declaración. También he le cambió el nombre para evitar confusiones:
string ExpandedFunc(int x)
En otras palabras, Func<int, string>
es un delegado que representa una función de tomar un argumento int
y devolviendo una string
.
Func<T, TResult>
se utiliza a menudo en LINQ, tanto para las proyecciones y predicados (en el último caso, TResult
es siempre bool
). Por ejemplo, se puede utilizar un Func<int, string>
para proyectar una secuencia de números enteros en una secuencia de cadenas. Las expresiones lambda se utilizan generalmente en LINQ para crear los delegados pertinentes:
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);
}
Resultados:
Value=3
Value=7
Value=10
Otros consejos
A Func<int, string>
come enteros y cadenas de devoluciones. Por lo tanto, lo que se come Ints y devuelve cadenas? ¿Qué tal esto ...
public string IntAsString( int i )
{
return i.ToString();
}
No, acabo de hacer una función que come enteros y devuelve cadenas. ¿Cómo voy a usarlo?
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"
No es muy atractivo, lo sé, pero esa es la simple idea de que una gran cantidad de trucos se basan en. Ahora, vamos a utilizar una vez 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
En lugar de llamar IntAsString en cada miembro, creé una referencia a él llama FNC (estas referencias a métodos se llaman delegados ) y se utiliza en su lugar. (Recuerde FNC come Ints y devuelve cadenas).
Este ejemplo no es muy atractivo, pero una tonelada de la materia inteligente verá se basa en la simple idea de las funciones, los delegados y métodos de extensión .
Uno de los mejores cebadores en estas cosas que he visto es aquí . Él tiene muchos más ejemplos reales. :)
Es un delegado que toma un int
como un parámetro y devuelve un valor de tipo string
.
Este es un ejemplo de su 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>
acepta un parámetro de valor int y devuelve un valor de cadena. He aquí un ejemplo en el que un método de soporte adicional es innecesaria.
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: El último tipo de objeto en Func (es decir, "string" en este ejemplo) es las funciones devuelven tipo (es decir, no limitado a primitivas, pero cualquier objeto). Por lo tanto, Func<int, bool, float>
acepta parámetros int y de valor bool, y devuelve un valor de coma flotante.
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