Une fois compilé, existe-t-il une différence entre:
delegate { x = 0; }
et
() => { x = 0 }
?
Une fois compilé, existe-t-il une différence entre:
delegate { x = 0; }
et
() => { x = 0 }
?
Réponse courte : non.
Plus de réponse qui peuvent ne pas être pertinentes:
Edit: Voici quelques liens pour les Expressions.
J'aime bien David réponse, mais je pensais être pédant. La question dit, "une Fois qu'il est compilé" - ce qui suggère que les deux expressions ont été compilées. Comment ont-ils pu compiler, mais avec un être converti en un délégué et un délégué d'une arborescence d'expression? C'est une question difficile - vous devez utiliser une autre caractéristique de méthodes anonymes; le seul qui n'est pas partagée par les expressions lambda. Si vous spécifiez une méthode anonyme sans spécifier une liste de paramètres à tous il est compatible avec tout type de délégué de retour nulle et sans out
paramètres. Armés de cette connaissance, nous devrions être en mesure de construire deux surcharges de rendre les expressions sans ambiguïté, mais très différents.
Mais la catastrophe! Au moins avec C# 3.0, vous ne pouvez pas convertir une expression lambda avec un bloc de corps dans une expression - et vous ne pouvez pas convertir une expression lambda avec une affectation dans le corps (même si elle est utilisée comme valeur de retour). Cela pourrait changer avec C# 4.0 et .NET 4.0, qui permettent plus d'être exprimé dans une arborescence d'expression. Donc, en d'autres termes, avec les exemples MojoFilter qui est arrivé à donner, les deux seront presque toujours être converti à la même chose. (Plus de détails dans une minute).
Nous pouvons utiliser le délégué paramètres truc si nous changeons le corps un peu:
using System;
using System.Linq.Expressions;
public class Test
{
static void Main()
{
int x = 0;
Foo( () => x );
Foo( delegate { return x; } );
}
static void Foo(Func<int, int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
static void Foo(Expression<Func<int>> func)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
Mais attendez! Nous pouvons distinguer entre les deux, même sans l'aide de l'expression des arbres, si nous sommes assez rusé. L'exemple ci-dessous utilise la résolution de surcharge règles (et le délégué anonyme correspondant truc)...
using System;
using System.Linq.Expressions;
public class Base
{
public void Foo(Action action)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
public class Derived : Base
{
public void Foo(Action<int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
int x = 0;
d.Foo( () => { x = 0; } );
d.Foo( delegate { x = 0; } );
}
}
Ouch. Rappelez-vous les enfants, à chaque fois que vous la surcharge des méthodes d'une classe de base, un petit chaton se met à pleurer.
Dans les deux exemples, il n'y a pas de différence, zéro.
L'expression
() => { x = 0 }
est une expression Lambda avec un corps d'instruction, elle ne peut donc pas être compilée en tant qu'arbre d'expression. En fait, il ne compile même pas, il faut un point-virgule après 0:
() => { x = 0; } //Lambda statement body
() => x = 0 // lambda expression body, could be an expression tree.
David B est correcte. Notez qu’il peut y avoir des avantages à utiliser des arborescences d’expression. LINQ to SQL va examiner l’arborescence de l’expression et convertissez-le en SQL.
Vous pouvez également jouer des tours avec des arbres lamdas et d’expression pour transmettre efficacement les noms des membres de la classe à un cadre dans une manière sécurisée de refactorisation. MOQ est un exemple de ceci.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.