item.FirstName)'/> item.FirstName)'/> item.FirstName)'/> Voglio capire l'espressione lambda in @ Html.DisplayFor (modelItem => item.FirstName) | webgamecafe.com

Domanda Voglio capire l'espressione lambda in @ Html.DisplayFor (modelItem => item.FirstName)


Sono abbastanza nuovo in C # e MVC e ho usato lambda in determinate occasioni, come per i metodi anonimi e su LINQ.

Di solito vedo espressioni lambda che assomigliano a questo:

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

Capisco che lambda = "va a". Non ho mai visto un'espressione lambda in cui il parametro sinistro non è usato.

Non so come tradurre questa espressione lambda però

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

Qualcuno può far luce su questo per me? Non dovrebbe essere questo

(modelItem => modelItem.FirstName)?

Ho preso questo da Microsoft Introduzione al tutorial MVC di ASP.NET.


44
2018-04-10 23:41


origine


risposte:


Un'espressione lambda è un modo per scrivere una funzione anonima, cioè una funzione senza un nome. Quello che hai sul lato sinistro della "freccia" sono i parametri della funzione, e quello che hai sul lato destro sono il corpo della funzione. Così, (x => x.Name) logicamente si traduce in qualcosa di simile string Function(Data x) { return x.Name } i tipi string e Data ovviamente varierà e sarà derivato dal contesto.

L'assenza del parametro sul lato sinistro si traduce in una funzione senza parametri, quindi questo (() => someVariable) logicamente si traduce in questo: string Function() { return someVariable; }

A questo punto potresti iniziare a chiedertelo, dove someVariable viene da, non è un parametro di funzione e non è definito nella funzione. Saresti corretto, una funzione come questa non si compilerebbe mai. Tuttavia, la funzione lambda come questa è perfettamente a posto, in quanto consente di sollevare le variabili dello scope esterno e di utilizzarle in questo modo. (Internamente viene creata una classe wrapper in cui le variabili utilizzate nell'espressione lambda diventano campi.)

Ora vediamo cosa model => item.FirstName si intende. Logicamente si tradurrebbe in string Function(Model model) { return item.FirstName; }. Fondamentalmente questa è una funzione con un parametro, ma questo parametro non è usato.

E ora, l'ultimo bit dell'informazione. Sebbene le espressioni lambda rappresentino funzioni alla fine, a volte vengono create non con lo scopo di essere effettivamente eseguite (sebbene potenzialmente possano farlo). Un'espressione lambda può essere rappresentata sotto forma di un albero di espressione. Ciò significa che invece di eseguirlo può essere parsed.

In questo caso particolare, il motore MVC no correre la funzione che rappresenta l'espressione lambda. Invece l'espressione è parsed in modo che il motore MVC sappia quale html emettere per questa particolare linea. Se l'elemento dati non proviene direttamente dall'oggetto modello, la parte sinistra dell'espressione lambda non ha importanza.


91
2018-04-11 00:20



penso che riguardi il ciclo di foreach. esempio:

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

var item deve essere usato perché ogni elemento nella sequenza è di tipo anonimo. model => item.firstName si intende (input parameter) => expression. non è possibile utilizzare il parametro di input perché memorizziamo l'attuale "elemento" in item.


6
2018-04-11 00:25



Sta usando una lambada senza parametri. Guarda questo domanda 

Fondamentalmente DisplayFor non usa il modello di parametro della funzione lambda (potrebbe essere qualsiasi cosa che direi usare _ o ()) e usa semplicemente la funzione lambda all'interno del ciclo for per usare displayfor contro di esso. DisplayFor richiede una funzione lambda.


4
2018-04-10 23:48



Ho anche faticato molto per capire i codici generati da Visual Studio. Invece di fornire una spiegazione generale sull'espressione lambda, vorrei mettere un contesto usando il framework ASP.NET MVC.

Supponiamo di aver preparato una classe Model (ad esempio Destination) con 2 attributi: City e ProvinceCode.

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

Dopo aver generato il controller e la vista, dovremmo ottenere i codici generati da Visual Studio come menzionato. Tuttavia, i codici generati sono alquanto difficili da comprendere, soprattutto per le righe di dati

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

Io solo indovina che il team MVC dovrebbe pensare che la classe helper Html dovrebbe essere utilizzata in modo coerente nel file cshtml. Così, hanno cercato di usare trucchi per passare il compilatore C #. In questo caso, modelItem non viene nemmeno utilizzato come parametro di input di questa espressione lambda. Non possiamo usare () come il tipo è NON corretta. Ecco perché, se sostituiamo modello o qualsiasi oggetto modello, l'espressione lambda funziona.

Per essere onesti, vorrei riscrivere i codici generati in una forma più leggibile. Invece di usare il html classe helper, possiamo semplicemente rendere l'output corretto come segue:

@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
2018-02-07 06:49