tresult parameter generic examples delegate c# func

c# - parameter - En pocas palabras, lo que se puede decir acerca de Func<>



generic delegates in c# (7)

He estado viendo Func <> por algún tiempo, y he logrado evitarlo (por ahora). Pero, ahora parece que no puedo esquivarlo para siempre. Por ejemplo, probé Dynamic Linq, pero casi todo fue en términos de Func <>. He probado uno de mis libros (C # 2008 / Deitel & Deitel) y también MSDN, pero todavía no lo he recibido. Todos saltan directamente en el tema.

  1. Lo que se puede decir (en pocas palabras) sobre Func <>
  2. ¿Puedo obtener algunos enlaces en la web que me permitan comenzar con este asunto?

Gracias por ayudar


Esto podría ayudar. Supongamos que cada vez que ves Func<int, string> piensas para ti mismo:

interface IFuncIntString { string Invoke(int x); }

Es decir, el delegado es un objeto que implementa esta interfaz. Tiene un solo método llamado Invoke que toma un int y devuelve una cadena.

Ahora agregue a eso la función de que puede omitir el "Invocar" en una llamada, y usted tiene un delegado.


Func <..., T> es delegado. donde T es el tipo de retorno, y todos los demás - parámetros de entrada.


Puedes comenzar con 101 muestras de Linq .

En resumen, Func<> es un delegado donde el último parámetro de tipo es el tipo de retorno.

Entonces, Func<int,bool> es un delegado que toma un parámetro int y devuelve un bool .


Si alguna vez has usado el operador => en c #, y probablemente lo hayas hecho, ya has usado Funcs. Simplemente no los has declarado explícitamente.

Por lo tanto, si escribes una declaración como

var peopleWhoLikeBlue = people.Where(person => person.FavoriteColor == "Blue");

estás pasando un Func<Person, bool> al método Where ().

Si quieres ser Wordy, puedes reescribir esa declaración de la siguiente manera:

Func<Person, bool> favoriteColorIsBlue = person => person.FavoriteColor == "Blue"; var peopleWhoLikeBlue = people.Where(favoriteColorIsBlue);

Y obtendrás el mismo resultado.


Func<> es un delegado genérico: es muy conveniente de usar, ya que no tiene que crear su propio delegado para cada combinación de tipo argumento / retorno.
Antes, tenías que escribir algo como:

public delegate long MyDelegate( int number ); public void Method( IEnumerable<int> list, MyDelegate myDelegate ) { foreach( var number in list ) { myDelegate( number ); } }

Tuvo que publicar su delegado para que un usuario pueda llamar a su método correctamente. Especialmente cuando necesitas un montón de delegados diferentes, terminaste publicando uno para cada lista de argumentos y tipo de devolución.
Con Func<> solo escribes:

public void Method( IEnumerable<int> list, Func<int, long> myDelegate ) { foreach( var number in list ) { myDelegate( number ); } }

Significa lo mismo que el primer ejemplo de código: Func<int, long> define un delegado que toma un argumento entero y devuelve un valor largo.

Por supuesto, también puede usar listas de parámetros más largas: Func<int, int, bool, long> todavía devolverá un valor largo mientras toma dos ints y un valor bool . Si desea un delegado sin valor de retorno, tendrá que usar Action<> , que se anulará como tipo de retorno.

EDITAR (por solicitud): Cómo llamar al método en mi ejemplo :

Para la persona que llama, no hay diferencia entre la solución con MyDelegate o Func<> . En ambos casos tiene tres opciones para llamar al método:

Usando una notación lambda (se requiere C # 3.0, probablemente la mejor solución para métodos cortos):

Method( myList, i => i * i );

Usando un método anónimo (se requiere C # 2.0):

Method( myList, delegate( int i ) { return i * i; } );

O usando un método real como argumento:

Method( myList, Square ); private static long Square( int number ) { return number * number; }


Func<...> es una familia de tipos de delegados, que devuelve algún valor y toma algunos argumentos; por ejemplo:

  • Func<int,bool> es simplemente algo que toma un int y devuelve un bool (el retorno siempre es al final); por ejemplo un predicado:

    int[] data = {1,2,3,4,5}; var odd = data.Where(i => i % 2 == 0);

  • Func<string> es un método que devuelve una cadena, como () => "hello world"; .

  • Func<DateDtime, TimeSpan, DateTime> podría ser algo como (when,howLong) => when + howLong;

Del mismo modo, hay una Action<...> que hace lo mismo pero sin un tipo de retorno.

No hay nada mágico en Func<...> : es solo una forma más simple de expresar delegados, mientras que a: usar genéricos (útil para LINQ), o b: no es necesario que busque los argumentos; si el tipo de delegado es algo oscuro (por ejemplo, PipeStreamImpersonationWorker ) puede ser difícil saber qué se necesita; si eso se expresara como una Action comparable, sería claro que no toma parámetros y devuelve el void .


Func<int> (por ejemplo) es un tipo (en la forma en que la string es un tipo). Así que lo usas para declarar variables, campos, parámetros, etc.

Representa un cálculo que se puede hacer cada vez que le pidas una respuesta:

Func<int> f = () => DateTime.Now.Second; // elsewhere... Console.WriteLine( f() );

Observa cómo puedes llamarlo como un método. Hay muchas versiones sobrecargadas de Func para admitir diferentes números de parámetros. El último argumento de tipo es el tipo de retorno.

Func<int, string> quoteInt = n => "/"" + n + "/""; Console.WriteLine( quoteInt(3) );

Func es un tipo de delegado. Puedes declarar el tuyo, pero es más fácil usar Func . Donde quieras devolver el void , usa Action lugar de Func . Solo necesita declarar delegados personalizados si necesita out o ref . Parámetros.

Al asignar un lambda a un Func , puede referirse a las variables locales. Esto es extremadamente poderoso; significa que un Func es más que un simple código; tiene datos Entonces, es como un objeto con un solo método (que técnicamente es: el método se llama Invoke y el compilador llama implícitamente ese método cuando llama a un delegado).

La sintaxis () => se puede colocar antes de cualquier expresión para decir "no hagas esto ahora, demora hasta más tarde". Le permite inicializar un delegado capturando el cálculo retrasado. Y luego la sintaxis () se puede colocar después del delegado para activar el cálculo. Entonces, el sufijo () es una especie de opuesto al prefijo () => .