Pourquoi ne pouvez-vous pas utiliser un paramètre ref ou out dans une expression lambda?
Je suis tombé sur l'erreur aujourd'hui et j'ai trouvé une solution de contournement, mais j'étais toujours curieux de savoir pourquoi il s'agit d'une erreur de compilation.
CS1628 : Impossible d'utiliser le paramètre "paramètre" dans ref ou out dans une méthode anonyme, une expression lambda ou une expression de requête
Voici un exemple simple:
private void Foo()
{
int value;
Bar(out value);
}
private void Bar(out int value)
{
value = 3;
int[] array = { 1, 2, 3, 4, 5 };
int newValue = array.Where(a => a == value).First();
}
Réponses:
Les lambdas ont l'apparence de changer la durée de vie des variables qu'ils capturent. Par exemple , l'expression lambda suivant provoque le paramètre p1 à vivre plus long que le cadre de la méthode actuelle en tant que sa valeur est accessible après la trame de procédé ne sont plus sur la pile
Une autre propriété des variables capturées est que les modifications apportées à la variable sont également visibles en dehors de l'expression lambda. Par exemple les impressions suivantes 42
Ces deux propriétés produisent un certain ensemble d'effets qui vont à l'encontre d'un paramètre ref de la manière suivante
Ce sont des propriétés quelque peu incompatibles et c'est l'une des raisons pour lesquelles elles ne sont pas autorisées dans les expressions lambda.
la source
ref
intérieur de l'expression lambda, mais le désir de l'utiliser n'a pas été nourri.Sous le capot, la méthode anonyme est implémentée en soulevant les variables capturées (ce qui est le but de votre corps de question) et en les stockant en tant que champs d'une classe générée par le compilateur. Il n'existe aucun moyen de stocker un paramètre
ref
ou enout
tant que champ. Eric Lippert en a discuté dans une entrée de blog . Notez qu'il existe une différence entre les variables capturées et les paramètres lambda. Vous pouvez avoir des "paramètres formels" comme les suivants car ils ne sont pas des variables capturées:la source
Vous pouvez mais vous devez définir explicitement tous les types afin
Est invalide, cependant
Est valable
la source
ref
ouout
, à l'intérieur d'un lambda. Il est clair si vous lisez l'exemple de code (essayez à nouveau de le relire). La réponse acceptée explique clairement pourquoi. Votre réponse concerne l'utilisationref
ou leout
paramètre du lambda. Totalement ne pas répondre à la question et parler d'autre choseComme il s'agit de l'un des meilleurs résultats pour "C # lambda ref" sur Google; Je sens que je dois développer les réponses ci-dessus. L'ancienne syntaxe de délégué anonyme (C # 2.0) fonctionne et prend en charge des signatures plus complexes (ainsi que des fermetures). Les délégués lambda et anonymes ont au moins partagé l'implémentation perçue dans le backend du compilateur (s'ils ne sont pas identiques) - et surtout, ils prennent en charge les fermetures.
Ce que j'essayais de faire lorsque j'ai fait la recherche, pour démontrer la syntaxe:
Gardez simplement à l'esprit que les Lambdas sont plus sûres d'un point de vue procédural et mathématique (en raison de la promotion de la valeur de référence mentionnée précédemment): vous pouvez ouvrir une boîte de vers. Réfléchissez bien lorsque vous utilisez cette syntaxe.
la source
(a, b, c, ref d) => {...}
et j'airef
été souligné en rouge avec le message d'erreur "Le paramètre '4' doit être déclaré avec le mot clé 'ref'". Facepalm! PS qu'est-ce que la "promotion de la valeur ref"?Et peut-être ça?
la source