2009-05-18 25 views

Respuesta

123

¿Está familiarizado con los delegados en general? Tengo una página sobre delegates and events que puede ayudar si no, aunque está más orientada a 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 los parámetros de tipo (T y TResult) con los correspondientes 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 usa a menudo en LINQ, tanto para proyecciones como para predicados (en este último caso, TResult es siempre bool). Por ejemplo, puede usar Func<int, string> para proyectar una secuencia de enteros en una secuencia de cadenas. Las expresiones lambda se utilizan generalmente en LINQ para crear los 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); 
} 

Resultados:

Value=3 
Value=7 
Value=10 
+2

"En otras palabras, es un delegado que representa una función que toma un argumento int y devuelve una cadena". Solo para evitar confusiones para otros aclararé que está hablando de Func aquí y no de Func . Es obvio si usted entiende los tipos genéricos y los delegados, pero para aquellos que no lo hacen es Func que kan delega en una función que toma un argumento int y devuelve una cadena. –

+0

Se aclarará cuando regrese a una PC más adelante. –

+8

Downvoters: proporcione razones ... –

22

Es un delegado que toma un int como parámetro y devuelve un valor de tipo string.

Aquí 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(); 
    } 
} 
+0

Gracias andrew. ¿Querías escribir func (1) en lugar de bar (1)? – zSynopsis

+1

Sí, lo hice!¡Gracias por la corrección! –

33

Un Func<int, string> come enteros y devuelve cadenas. Entonces, ¿qué come y devuelve cadenas? ¿Qué tal esto ...

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

Allí, acabo de crear una función que come y devuelve cadenas. ¿Cómo lo usaría?

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 muy sexy, lo sé, pero esa es la idea simple en la que se basan muchos trucos. Ahora, usemos un Func en su lugar.

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, he creado una referencia a él llama FNC (estas referencias a métodos se llaman delegates) y se utiliza en su lugar. (Recuerde que fnc come ints y returns strings).

Este ejemplo no es muy sexy, pero muchas de las cosas inteligentes que verá se basan en la simple idea de funciones, delegados y extension methods.

Uno de los mejores cartillas en esta materia que he visto es here. Él tiene muchos ejemplos más reales. :)

+4

Me gusta esta explicación –

+0

@Therealnapster me gusta también pero me gusta más tu nombre. – BKSpurgeon