On me pose souvent cette question et je pensais avoir des idées sur la meilleure façon de décrire la différence.
Réponses
Trop de publicités?Ils sont en fait deux choses très différentes. "Délégué" est en fait le nom d'une variable qui contient une référence à une méthode ou d'un lambda, et un lambda est une méthode sans un nom définitif.
Les Lambdas sont très bien comme les autres méthodes, à l'exception de quelques différences subtiles.
- Une méthode normale est définie dans une "déclaration" et attaché à un nom définitif, alors qu'un lambda est définie "à la volée" dans une "expression" et n'a pas de nom définitif.
- Certains lambdas peuvent être utilisés avec .NET des arbres d'expression, alors que les méthodes ne peuvent pas.
Un délégué est définie comme ceci:
delegate Int32 BinaryIntOp(Int32 x, Int32 y);
Une variable de type BinaryIntOp peut avoir une méthode ou d'un labmda affecté à elle, aussi longtemps que la signature est la même: deux Int32 arguments, et un Int32 retour.
Un lambda peut être définie comme ceci:
BinaryIntOp sumOfSquares = (a, b) => a*a + b*b;
Une autre chose à noter est que, bien que le générique Func et types d'Action sont souvent considérés comme des "lambda" types, ils sont comme tous les autres délégués. La bonne chose à leur sujet est qu'ils sont essentiellement de définir un nom pour tout type de délégué, vous pourriez avoir besoin (jusqu'à 4 paramètres, mais vous pouvez certainement ajouter plus de votre propre). Donc, si vous êtes en utilisant une grande variété de types délégués, mais aucun plus d'une fois, vous pouvez éviter d'encombrer votre code avec des déclarations de délégués par l'aide de la touche Func et l'Action.
Voici une illustration de la façon dont la touche Func et l'Action "ne sont pas seulement pour les lambdas":
Int32 DiffOfSquares(Int32 x, Int32 y)
{
return x*x - y*y;
}
Func<Int32, Int32, Int32> funcPtr = DiffOfSquares;
Une autre chose utile à savoir, c'est que délégué des types (pas de méthodes elles-mêmes) avec la même signature, mais des noms différents ne seront pas implicitement coulé les uns aux autres. Cela comprend la touche Func et l'Action des délégués. Toutefois, si la signature est identique, vous pouvez convertir explicitement entre eux.
Allez le mile supplémentaire.... En C# les fonctions sont flexibles, avec l'utilisation des lambdas et les délégués. Mais le C# n'a pas de "premier de la classe des fonctions". Vous pouvez utiliser un nom de la fonction attribuée à un délégué variable afin de créer un objet représentant cette fonction. Mais c'est vraiment un compilateur truc. Si vous démarrez une déclaration par écrit le nom de la fonction suivi d'un point (c'est à dire essayer de faire de l'accès des membres sur la fonction elle-même), vous trouverez il n'y a pas que les membres de référence. Pas même à celles de l'Objet. Cela empêche le programmeur de faire utile (et potentiellement dangereux, bien sûr) des choses telles que l'ajout de méthodes d'extension qui peut être appelé à n'importe quelle fonction. Le meilleur que vous pouvez faire est d'étendre le Délégué de la classe elle-même, qui est certainement utile, mais pas tout à fait autant.
Mise à jour: voir Aussi Karg réponse illustrant la différence entre les délégués anonymes contre les méthodes et les lambdas.
Mise à jour 2: James Hart joue un rôle important, bien que très technique, notez que les lambdas et les délégués ne sont pas .NET des entités (c'est à dire le CLR a pas de concept d'un délégué ou lambda), mais plutôt qu'ils sont le cadre et les constructions de langage.
La question est un peu ambigu, ce qui explique la grande disparité dans les réponses que vous obtenez.
Vous avez demandé quelle est la différence entre les lambdas et les délégués dans le .NET framework, qui pourrait être l'un des un certain nombre de choses. Demandez-vous:
Quelle est la différence entre les expressions lambda et anonyme délégués dans le C# (ou VB.NET) langue?
Quelle est la différence entre le Système.Linq.Les Expressions.LambdaExpression des objets et du Système.Délégué objets .NET 3.5?
Ou quelque chose quelque part entre ou autour de ces extrêmes?
Certaines personnes semblent être en essayant de vous donner la réponse à la question " quelle est la différence entre les expressions Lambda C# et .NET Système.Délégué?', ce qui ne veut pas faire beaucoup de sens.
L' .NET framework n'est pas, en soi, de comprendre les concepts de délégués anonymes, des expressions lambda, ou des fermetures - ce sont toutes des choses définies par les spécifications de langue. Pensez à la façon dont le compilateur C# se traduit par la définition d'une méthode anonyme dans une méthode d'une classe générée avec membre des variables pour contenir la fermeture de l'état; pour .NET, rien n'est anonyme sur le délégué, c'est juste un anonyme pour le programmeur C# écrit il. C'est vrai aussi d'une lambda expression attribuée à un type de délégué.
Qu'est-ce .NET NE comprends, c'est l'idée d'un délégué - un type qui décrit une méthode de signature, dont les instances représentent soit lié à des appels à des méthodes spécifiques sur des objets spécifiques, ou indépendant des appels à une méthode particulière à un type particulier qui peut être invoquée à l'encontre de tout objet de ce type, où ladite méthode adhère à ladite signature. Ces types héritent tous de Système.Délégué.
.NET 3.5 introduit également le Système.Linq.Les Expressions de l'espace de noms qui contient des classes pour décrire les expressions de code - et peut donc représenter, reliées ou non, les appels de méthodes sur des types particuliers ou des objets. LambdaExpression instances peuvent ensuite être compilées dans des délégués (en vertu de laquelle une dynamique de la méthode basée sur la structure de l'expression est codegenned, et un délégué pointeur est retourné).
En C#, vous pouvez produire des instances de Système.Les Expressions.Types d'Expression par l'attribution d'une lambda expression à une variable de ladite type, qui va produire le code approprié pour construire l'expression au moment de l'exécution.
Bien sûr, si vous avez été demander quelle est la différence entre les expressions lambda et les méthodes anonymes en C#, après tout, tout cela est assez bien irelevant, et dans ce cas, la principale différence est la brièveté, qui se penche vers les délégués anonymes lorsque vous n'avez pas de soins sur les paramètres et je ne prévois pas retourner une valeur, et vers les lambdas quand vous voulez type inferenced les paramètres et les types de retour.
Et les expressions lambda support d'expression de la génération.
Une différence est qu'un délégué anonyme peut omettre des paramètres alors qu'un lambda doit correspondre à la signature exacte. Donné:
public delegate string TestDelegate(int i);
public void Test(TestDelegate d)
{}
vous pouvez l'appeler des quatre manières suivantes (notez que la deuxième ligne a un délégué anonyme qui n'a aucun paramètre):
Test(delegate(int i) { return String.Empty; });
Test(delegate { return String.Empty; });
Test(i => String.Empty);
Test(D);
private string D(int i)
{
return String.Empty;
}
Vous ne pouvez pas transmettre une expression lambda sans paramètres ni une méthode sans paramètres. Ce ne sont pas autorisés:
Test(() => String.Empty); //Not allowed, lambda must match signature
Test(D2); //Not allowed, method must match signature
private string D2()
{
return String.Empty;
}