2011-07-20 60 views
9

從ASP.NET 2.0(VB)到MVC 3(C#)去,我對正用於查看的語法很困惑。語法問題:@ Html.LabelFor(M => m.UserName)

@Html.LabelFor(m => m.UserName) 

從哪裏來的?我唯一的猜測是它代表了被傳入視圖的模型。我試着將m更改爲c,它仍然正常工作。

是,涉及到「=>」更多的MVC,C#,或剃刀元件的語法的一部分?

+0

@NoProblemBabe,有人在這裏做:http://stackoverflow.com/questions/2595947/asp-net-mvc-label-for – 2011-09-29 12:13:44

回答

9

如果是來自沒有m

這是一個lambda表達式的參數。

我唯一的猜測是它代表了被傳遞到視圖中的模型。我試着將m更改爲c,它仍然正常工作。

這是因爲該名稱並不重要。它只是一個參數名稱,它並不實際引用任何現有的變量。

是涉及MVC,C#或Razor元素的「=>」語法的一部分嗎?

這是C#,但LabelFor使用什麼編譯器翻譯m => m.UserName到提取什麼它需要建立標籤。

這是一個非常深刻的複雜主題。我建議你找一本適合你的書(例如,C#深度對這個主題非常好)來了解更多。你想了解一下lambda表達式和表達式樹。

+0

我不需要一本書。 – Tocco

+1

C#中的+1深入 - Jon Skeet愛你... –

3

這是一個Lambda表達式,link

該協議是這樣的:米是接收在給定的circunstance模型的實例的變量。
在labelFor中,它將調用一個編譯時創建的類,該類有一個方法來執行您作爲LabelFor參數傳遞的內容。

lambda表達式可以通過委託進行切換,以同樣的結果,除了未成年人,真的小幅性能提升,一次。

一般的想法是你傳遞一個方法在LabelFor方法的某個地方執行。

例如: 方法:

public void Dummy(Action<string> action) 
{ 
    if(iFeelLikeIt) {action("I feel Like it");} 
} 

應作爲:

Dummy(msg => MessageBox.Show(msg)); 
1

這是Lambda表達式。從MSDN
lambda表達式是一個匿名函數,可以包含表達式和語句,並可用於創建委託或表達式樹類型。

所有的lambda表達式都使用lambda運算符=>,它被讀作「去往」。 lambda運算符的左側指定輸入參數(如果有的話),右側保存表達式或語句塊。 lambda表達式x => x * x被讀取爲「x轉到x次x」。

8

這是自C#3.0以來出現的語法技巧(我想;也許3.5)。

如果你在代碼中寫這個(和你的Razor視圖不會得到翻譯成C#代碼文件編譯之前,這的確讓在代碼),有兩種可能的方式,編譯器可以把它取決於編譯上下文。

如果方法LabelFor()需要一個委託,它將被編譯爲一個匿名方法。或者,如果方法預計爲System.Linq.Expressions.Expression<Func>類型,則構建expression tree。這就是你的情況。

這樣做的原因convul​​ted語法是表達式樹包含足夠的信息,即(與反射相結合)的方法LabelFor()可以提取實際屬性到你指。如果您只是簡單地將其傳遞爲LabelFor(Model.UserName),那麼LabelFor()就沒有足夠的信息來執行此操作。它只會得到UserName屬性的值。但是現在它知道它來自哪裏,並且可以使用更多的反射來查看屬性的屬性。屬性如DisplayFormatRequired等。

m(或c或其他)實際上是你的模型。 LabelFor是一種擴展方法,它只是將您的模型傳遞迴您的Lambda表達式,以便整個表達式樹技巧可以工作。你也可以像LabelFor(x=>Model.UserName)這樣寫,但我認爲它不會起作用(儘管我還沒有嘗試過,也許它會這樣)。

+0

啊,謝謝你解釋擴展語法背後的原因。 – rkw

+0

Lambda表達式的語法技巧?他們是一個非常重要的語言功能! –

+0

是的。這是一個非常重要的語法技巧。 :)好的,好吧,我想很多語言功能可能被稱爲「語法技巧」。我使用這個術語來表示「不需要使用該功能就可以完成的任務,除非寫入更加繁瑣」。例如,一個lambda表達式'x => x * 2'可以用更古老的'delegate(int x){return x * 2; '語法。或者,如果它用於構建'Expression ',那麼您可以使用顯式的'Expression'方法來構建樹。當然,代碼變得單調乏味。但它仍然可以完成。 –

0

LabelFor是一個Razor函數,它內部具有Model的知識。換句話說,模型駐留在LabelFor函數邏輯中。當你傳遞lambda表達式時,你傳遞一個匿名函數給LabelFor,所以它知道如何處理它的內部Model對象來提取信息。

通常你會傳遞一個Model作爲參數,而LabelFor將使用內部邏輯來提取所需的信息。但是在這種格式下,情況恰恰相反。 LabelFor在內部知道參數(模型),但它不知道如何處理它。您通過傳遞Lambda函數來告訴它該做什麼。

當您運行代碼時,您將Lambda表達式作爲參數傳遞給LabelFor。 LabelFor,採用lambda表達式並將其傳遞給Model對象的內部副本。 Lambda表達式返回Model對象的UserName屬性,LabelFor使用它來構建HTML代碼。