web-dev-qa-db-fra.com

Je veux comprendre l'expression lambda dans @ Html.DisplayFor (modelItem => item.FirstName)

Je suis assez nouveau en C # et MVC et j'ai utilisé des lambdas à certaines occasions, comme pour les méthodes anonymes et sur LINQ.

Habituellement, je vois des expressions lambda qui ressemblent à ceci:

(x => x.Name), (x => { Console.WriteLine(x))

Je comprends que lambda = "va à". Je n'ai jamais vu une expression lambda où le paramètre gauche n'est pas utilisé.

Je ne sais pas comment traduire cette expression lambda

@Html.DisplayFor(modelItem => item.FirstName)

Quelqu'un peut-il faire la lumière sur celui-ci pour moi? Cela ne devrait-il pas être

(modelItem => modelItem.FirstName)?

Je l'ai obtenu de Microsoft Introduction au tutoriel ASP.NET MVC .

46
Jan Carlo Viray

Une expression lambda est un moyen d'écrire une fonction anonyme, c'est-à-dire une fonction sans nom. Ce que vous avez sur le côté gauche de la "flèche" sont les paramètres de la fonction, et ce que vous avez sur le côté droit sont le corps de la fonction. Ainsi, (x => x.Name) Se traduit logiquement par quelque chose comme string Function(Data x) { return x.Name } les types string et Data varieront évidemment et seront dérivés du contexte.

L'absence du paramètre de gauche se traduit par une fonction sans paramètres, de sorte que ce (() => someVariable) Se traduit logiquement par ceci: string Function() { return someVariable; }

À ce stade, vous pourriez commencer à vous demander d'où vient someVariable, ce n'est pas un paramètre de fonction et il n'est pas défini dans la fonction. Vous auriez raison, une fonction comme celle-ci ne se compilerait jamais. Cependant, la fonction lambda comme celle-ci est parfaitement correcte, car elle permet de lever et d'utiliser les variables de portée externe de cette façon. (En interne, une classe wrapper est créée dans laquelle les variables utilisées dans l'expression lambda deviennent des champs.)

Voyons maintenant ce que signifie model => item.FirstName. Logiquement, cela se traduirait par string Function(Model model) { return item.FirstName; }. Fondamentalement, c'est une fonction avec un paramètre, mais ce paramètre n'est pas utilisé.

Et maintenant, le dernier bit de l'information. Bien que les expressions lambda représentent des fonctions à la fin, parfois elles ne sont pas créées dans le but d'être réellement exécutées (bien qu'elles le puissent potentiellement). Une expression lambda peut être représentée sous la forme d'un arbre d'expression. Cela signifie qu'au lieu de l'exécuter, il peut être analysé.

Dans ce cas particulier, le moteur MVC n'a pas run la fonction représentée par l'expression lambda. Au lieu de cela, l'expression est analysée pour que le moteur MVC sache quel code HTML émettre pour cette ligne particulière. Si votre élément de données ne provient pas directement de votre objet modèle, la partie gauche de l'expression lambda n'a pas d'importance.

97
Andrew Savinykh

je pense qu'il s'agit de la boucle foreach. exemple:

@foreach(var item in model) 
{ 
 <td> 
     @html.displayfor(model => item.firstName) </td>
 </td>     
}

var item doit être utilisé car chaque élément de la séquence est de type anonyme. model => item.firstName veux dire (input parameter) => expression. vous ne pouvez pas utiliser le paramètre d'entrée car nous stockons l '"élément" actuel dans item.

6
varg

Il utilise une lambada sans paramètre. Voir ceci question

Fondamentalement, DisplayFor n'utilise pas le modèle de paramètre de la fonction lambda (cela pourrait être tout ce que je dirais utiliser _ ou ()) et utilise simplement la fonction lambda dans la boucle for pour utiliser displayfor contre. DisplayFor nécessite une fonction lambda.

4
GraemeMiller

J'ai également eu beaucoup de mal à comprendre les codes générés par Visual Studio. Au lieu de fournir une explication générale sur l'expression lambda, je voudrais mettre un contexte en utilisant le framework ASP.NET MVC.

Supposons que nous ayons préparé une classe Model (par exemple Destination) avec 2 attributs: City et ProvinceCode.

public class Destination
{
    public string City { get; set; }
    public string ProvinceCode { get; set; }
}

Après avoir généré le contrôleur et la vue, nous devrions obtenir les codes générés par Visual Studio comme mentionné. Pourtant, les codes générés sont quelque peu difficiles à comprendre, en particulier pour les lignes de données

@Html.DisplayFor(modelItem => item.City)

Je viens de deviner que l'équipe MVC devrait penser que la classe d'assistance Html devrait être utilisée de manière cohérente dans le fichier cshtml. Ainsi, ils ont essayé d'utiliser des astuces pour passer le compilateur C #. Dans ce cas, modelItem n'est même pas utilisé comme paramètre d'entrée de cette expression lambda. Nous ne pouvons pas utiliser () car le type est PAS correct. C'est pourquoi, si nous remplaçons modèle ou tout autre objet modèle, l'expression lambda fonctionne.

Pour être honnête, je voudrais réécrire les codes générés sous une forme plus lisible. Au lieu d'utiliser la classe d'assistance Html, nous pouvons simplement restituer la sortie correcte comme suit:

@foreach (var item in Model) {
<tr>        
    <td>  
        @* Code Generated by Visual Studio. modelItem is a dummy param *@
        @Html.DisplayFor(modelItem => item.City)
    </td>
    <td>
        @* A better way - simply get rid of Html helper class *@
        @item.ProvinceCode
    </td>
</tr>
}
1
Peter Chung