Métodos anónimos y expresiones lambda en C#
En C# 2.0 se incluyeron los método anónimos en el lenguaje, y en C# 3.0, las expresiones lambda mostraba otra forma de realizar lo mismo, llegando incluso a veces a ser la elección preferida de uso en lugar de los métodos anónimos.
Sin embargo, podemos llegar a tener la necesidad de realizar acciones que sólo son posibles realizarlas a través de métodos anónimos (un método anónimo podría ser convertido en delegados con varias firmas), por lo que conocer ambas y no descartar ninguna, es realmente algo a tener en cuenta.
Métodos anónimos
Un método anónimo es un método, el cual carece de un nombre.
Lo que contiene es el cuerpo del propio método que es lo que ejecutaremos. De hecho, un método anónimo nos ofrece la posibilidad de pasar un bloque de código como un parámetro de delegado.
Los métodos anónimos crearán instancias de delegados, reduciendo así la sobrecarga.
Para lograr todo esto, declararemos el delegado y su firma, y posteriormente indicaremos el código del mismo.
También debemos tener en cuenta que no tenemos porqué especificar el tipo de dato que devolverá, ya que será inferido dentro del cuerpo del método que lancemos.
La mejor forma no obstante, es ver todo esto con un ejemplo.
A continuación, escribiré un código que representa un método anónimo en C#:
using System; namespace AnonymousMethods { public class Program { private delegate double Mathematical(double value); public static void Main(string[] args) { Console.WriteLine("Started"); Console.WriteLine(); Mathematical doublePower = delegate (double value) { return Math.Pow(value, 2); }; Mathematical halfValue = delegate (double value) { return value / 2; }; Console.WriteLine(doublePower(3)); Console.WriteLine(halfValue(3)); Console.WriteLine(); Console.WriteLine("Press any key to close"); Console.ReadKey(); } } }
Si observamos este ejemplo, veremos que hemos declarado un delegado (Mathematical), y hemos declarado dos métodos dentro de Main que utilizando el mismo delegado, realiza dos cálculos diferentes. Uno el valor elevado a 2, y otro el valor dividido por 2, obteniendo 9 y 1.5.
Pero para hacer un poco más sólida la potencia de los métodos anónimos, voy a preparar otro ejemplo sensiblemente diferente.
using System; namespace AnonymousMethods { public class Program { private delegate void Writer(string text); private static void WriteConsole(string text) { Console.WriteLine(text); } public static void Main(string[] args) { Console.WriteLine("Started"); Console.WriteLine(); Writer writer = new Writer(WriteConsole); writer("Sample text from an anonymous method"); Console.WriteLine(); Console.WriteLine("Press any key to close"); Console.ReadKey(); } } }
En esta ocasión, vemos como además de declarar un delegado, hemos declarado un método anónimo, es decir, hemos instanciado un delegado, de otra manera.
Expresiones lambda
Una expresión lambda es una función o método anónimo con el que podemos crear tipo delegados y árboles de expresiones.
Las expresiones lambda suelen usarse para crear expresiones LINQ.
Como características generales a la hora de utilizar y crear expresiones lambda, hay que tener en cuenta que debemos indicar los parámetros de entrada.
Lo mejor que podemos hacer una vez más, es ver esto con un ejemplo de código:
using System; namespace AnonymousMethods { public class Program { private delegate double Mathematical(double value); public static void Main(string[] args) { Console.WriteLine("Started"); Console.WriteLine(); Mathematical doublePower = (double value) => { return Math.Pow(value, 2); }; Mathematical halfValue = (double value) => { return value / 2; }; Console.WriteLine(doublePower(3)); Console.WriteLine(halfValue(3)); Console.WriteLine(); Console.WriteLine("Press any key to close"); Console.ReadKey(); } } }
No obstante, las expresiones lambda de este ejemplo, también podrían ser sustituidas por estas otras:
Mathematical doublePower = value => Math.Pow(value, 2); Mathematical halfValue = value => value / 2;
Tenga en cuenta que el operador lambda => tiene siempre una prioridad alta dentro del proceso de ejecución.
Y así, podemos combinar diferentes llamadas y acciones, con parámetros o sin ellos.
De hecho, un ejemplo de más de un parámetro podría ser:
private delegate bool IsValidSizeText(string text, int length); // ... IsValidSizeText hasCorrectSize = (string text, int length) => text.Length <= length; Console.WriteLine(hasCorrectSize("Ejemplo", 5)); Console.WriteLine(hasCorrectSize("Ejemplo", 7));
También podríamos hacer uso de una expresión lambda sin parámetros:
() => MyMethod()
Métodos anónimos genéricos
Como extra de esta entrada, quería comentar la posibilidad que tenemos de mezclar genéricos y métodos anónimos.
Y es que dentro de los métodos anónimos podemos declararlos como genéricos para poder usar cualquier tipo de datos tal y como veremos a continuación.
La forma de plantear esto quedaría de la siguiente forma:
using System; namespace AnonymousMethods { public class Program { private delegate double Mathematical<T>(T value); public static void Main(string[] args) { Console.WriteLine("Started"); Console.WriteLine(); Mathematical<double> doublePower = delegate (double value) { return Math.Pow(value, 2); }; Mathematical<int> halfValue = delegate (int value) { return value / 2; }; Console.WriteLine(doublePower(3)); Console.WriteLine(halfValue(3)); Console.WriteLine(); Console.WriteLine("Press any key to close"); Console.ReadKey(); } } }
Como podemos observar,
es posible jugar con métodos anónimos y expresiones lambda, e incluso extender su uso a través del uso de métodos anónimos genéricos.
Espero que todo esto te sirva de ayuda.
¡Happy Coding!
4 Responsesso far
¿Cómo se declara un delegado anónimo con un parámetro de tipo entero que retorne bool?
Gracias.
hola un gusto, viendo lo que estas necesitando, creo que esto es a lo que necesitas:
Console.Write(«Digita un numero: «);
int parametro = Int32.Parse(Console.ReadLine());
Func del = (numero) => (numero > 0);
if (del(parametro))
{
Console.WriteLine(«El numero es positivo»);
Console.ReadKey();
}
else
{
Console.WriteLine(«El numero es negativo»);
Console.ReadKey();
}
es un ejemplo practico, para calcular si un numero introducido es positivo o negativo, espero te ayude.
internal static class Program
{
public static Func MyFunc;
internal static void Run()
{
MyFunc = x => x % 2 == 0;
}
private static void Main()
{
Run();
bool field = MyFunc(4);
}
}
Gracias!! la mejor explicación de todas!