Même si je vais me concentrer sur un point, j'ai commencer par vous donner de mes 2 cents sur l'ensemble de la question de la performance. À moins que les différences sont grandes ou de l'utilisation est intensive, je n'ai pas pris la peine de microsecondes qui ne sont pas d'une quelconque différence visible à l'utilisateur. Je tiens à souligner que je ne n'avez pas de soins lors de l'examen de la non-intensif appelées méthodes. Où je dois performance spéciale de considérations sur la conception de l'application elle-même. - Je me soucier de la mise en cache, à propos de l'utilisation des threads, sur des moyens astucieux pour l'appel de méthodes (si plusieurs appels ou essayer de faire un seul appel), que ce soit à la piscine des connexions ou non, etc., etc. En fait j'ai l'habitude de ne pas se focaliser sur la performance brute, mais sur scalibility. Je ne m'inquiète pas si il fonctionne mieux par une minuscule tranche de nanoseconde pour un seul utilisateur, mais je me soucie beaucoup avoir la possibilité de charger le système avec de grandes quantités d'utilisateurs simultanés, sans remarquer l'impact.
Cela dit, voici mon avis sur le point 1. J'aime les méthodes anonymes. Ils me donnent une grande flexibilité et le code de l'élégance. L'autre grande caractéristique sur les méthodes anonymes est qu'ils me permettent d'utiliser directement les variables locales de la méthode conteneur (à partir d'un C# point de vue, non pas à partir d'un IL point de vue, bien sûr). Ils m'épargner des charges de code souvent. Quand dois-je utiliser des méthodes anonymes? Evey seule fois sur le morceau de code que j'ai besoin n'est pas nécessaire d'ailleurs. Si elle est utilisée dans deux endroits différents, je n'aime pas copier-coller comme un réutiliser la technique, donc je vais utiliser une plaine ol délégué. Donc, tout comme shoosh répondu, il n'est pas bon d'avoir la duplication de code. En théorie, il n'existe pas de différences de performances comme anonyms sont C# astuces, pas de IL des trucs.
La plupart de ce que je pense sur les méthodes anonymes s'applique aux expressions lambda, que ce dernier peut être utilisé comme une syntaxe compacte pour représenter les méthodes anonymes. Supposons la méthode suivante:
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);
}
}
Il reçoit un tableau de chaînes de caractères et pour chacun d'eux, il va appeler la méthode adoptée. Si cette méthode retourne true, on va dire "Trouvé...". Vous pouvez appeler cette méthode de la façon suivante:
string[] names = {"Alice", "Bob", "Charles"};
DoSomethingMethod(names, delegate(string p) { return p == "Alice"; });
Mais, vous pouvez aussi appeler cela de la manière suivante:
DoSomethingMethod(names, p => p == "Alice");
Il n'y a pas de différence dans IL entre les deux, l'une à l'aide de l'expression Lambda est beaucoup plus lisible. Encore une fois, il n'y a pas d'impact sur les performances de tous ces compilateur C# astuces (pas de compilateur JIT de trucs). Tout comme je n'ai pas l'impression de nous abuser des méthodes anonymes, je n'ai pas l'impression de nous abuser des Lambda expressions pour représenter les méthodes anonymes. Bien sûr, la même logique s'applique à code à répétition: à ne pas faire lambdas, l'utilisation régulière des délégués. Il existe d'autres restrictions qui vous conduira à revenir à des méthodes anonymes ou de la plaine des délégués, comme ou ref argument de passage.
Les autres belles choses sur les expressions Lambda, c'est que l'exacte même syntaxe n'a pas besoin de représenter une méthode anonyme. Les expressions Lambda peut aussi représenter... vous l'aurez deviné, les expressions. Prenons l'exemple suivant:
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());
}
}
Avis légèrement différent de la signature. Le deuxième paramètre reçoit une expression et non d'un délégué. Le moyen d'appeler cette méthode serait:
DoSomethingExpression(names, p => p == "Alice");
Ce qui est exactement le même que l'appel que nous avons fait lors de la création d'une méthode anonyme avec un lambda. La différence ici est que nous ne sommes pas de la création d'une méthode anonyme, mais la création d'une arborescence d'expression. C'est en raison de ces arbres d'expression que l'on peut alors traduire les expressions lambda de SQL, qui est ce que Linq 2 SQL, par exemple, au lieu d'exécuter des trucs dans le moteur pour chaque clause comme le Où, le Sélectionner, etc. La bonne chose est que la syntaxe d'appel est la même que vous êtes en train de créer une méthode anonyme ou l'envoi d'une expression.