Aunque me centraré en el punto uno, empiezo por dar mis 2 centavos en todo el tema del rendimiento. A menos que las diferencias sean grandes o el uso sea intenso, generalmente no me preocupo por los microsegundos que cuando se agregan no representan una diferencia visible para el usuario. Enfatizo que solo no me importa cuando considero métodos llamados no intensivos. Donde sí tengo consideraciones de rendimiento especiales es en la forma en que diseño la aplicación en sí. Me importa el almacenamiento en caché, sobre el uso de hilos, sobre formas inteligentes de llamar a métodos (ya sea para hacer varias llamadas o para intentar hacer una sola llamada), si unir conexiones o no, etc., etc. De hecho, suelo donar no se centran en el rendimiento en bruto, sino en la escalabilidad. No me importa si funciona mejor con una pequeña fracción de nanosegundo para un solo usuario, pero me preocupa mucho poder cargar el sistema con grandes cantidades de usuarios simultáneos sin notar el impacto.
Habiendo dicho eso, aquí va mi opinión sobre el punto 1. Me encantan los métodos anónimos. Me dan una gran flexibilidad y elegancia de código. La otra gran característica de los métodos anónimos es que me permiten usar directamente las variables locales desde el método contenedor (desde una perspectiva C#, no desde una perspectiva IL, por supuesto). Me ahorran mucho código a menudo. ¿Cuándo uso métodos anónimos? Solo una vez el pedazo de código que necesito no es necesario en otro lado. Si se usa en dos lugares diferentes, no me gusta copiar y pegar como técnica de reutilización, así que usaré un simple delegado. Entonces, al igual que respondió shoosh, no es bueno tener duplicación de código. En teoría, no hay diferencias de rendimiento ya que los anónimos son trucos de C#, no cosas de IL.
La mayor parte de lo que pienso sobre los métodos anónimos se aplica a las expresiones lambda, ya que este último se puede usar como una sintaxis compacta para representar métodos anónimos. Vamos a suponer que el siguiente método:
public static void DoSomethingMethod(string[] names, Func<string, bool> myExpression)
{
Console.WriteLine("Lambda used to represent an anonymous method");
foreach (var item in names)
{
if (myExpression(item))
Console.WriteLine("Found {0}", item);
}
}
Recibe una matriz de cadenas y para cada uno de ellos, se llamará al método se le ha pasado. Si ese método devuelve verdadero, dirá "Encontrado ...". Puede llamar a este método de la siguiente manera:
string[] names = {"Alice", "Bob", "Charles"};
DoSomethingMethod(names, delegate(string p) { return p == "Alice"; });
embargo, también se puede llamar de la siguiente manera:
DoSomethingMethod(names, p => p == "Alice");
No hay diferencia en IL entre los dos, es que el uso de la La expresión Lambda es mucho más legible. Una vez más, no hay impacto en el rendimiento ya que estos son todos trucos del compilador de C# (no trucos del compilador JIT). De la misma manera que no me parece que usemos demasiado los métodos anónimos, no creo que exageremos las expresiones de Lambda para representar métodos anónimos. Por supuesto, la misma lógica se aplica al código repetido: No hagas lambdas, usa delegados regulares. Existen otras restricciones que lo llevan de regreso a métodos anónimos o simples delegados, como pasar o rechazar argumentos.
Las otras cosas agradables sobre las expresiones Lambda es que la misma sintaxis exacta no necesita representar un método anónimo. Las expresiones Lambda también pueden representar ... adivinaste, expresiones. Tome el siguiente ejemplo:
public static void DoSomethingExpression(string[] names, System.Linq.Expressions.Expression<Func<string, bool>> myExpression)
{
Console.WriteLine("Lambda used to represent an expression");
BinaryExpression bExpr = myExpression.Body as BinaryExpression;
if (bExpr == null)
return;
Console.WriteLine("It is a binary expression");
Console.WriteLine("The node type is {0}", bExpr.NodeType.ToString());
Console.WriteLine("The left side is {0}", bExpr.Left.NodeType.ToString());
Console.WriteLine("The right side is {0}", bExpr.Right.NodeType.ToString());
if (bExpr.Right.NodeType == ExpressionType.Constant)
{
ConstantExpression right = (ConstantExpression)bExpr.Right;
Console.WriteLine("The value of the right side is {0}", right.Value.ToString());
}
}
Observe la firma ligeramente diferente. El segundo parámetro recibe una expresión y no un delegado. La forma de llamar a este método sería:
DoSomethingExpression(names, p => p == "Alice");
¿Qué es exactamente la misma que la llamada que hicimos al crear un método anónimo con una lambda. La diferencia aquí es que no estamos creando un método anónimo, sino creando un árbol de expresiones. Es debido a estos árboles de expresiones que podemos traducir expresiones lambda a SQL, que es lo que Linq 2 SQL hace, por ejemplo, en lugar de ejecutar cosas en el motor para cada cláusula, como Where, Select, etc. Lo bueno es que la sintaxis de llamada es la misma ya sea que esté creando un método anónimo o enviando una expresión.
Le recomiendo que visite www.lambdaexpression.net – Delashmate
dominio @Delashmate asumido por los spammers ahora – ozz