[英]How and why inline helper methods evaluating types at runtime?
如您所知,我們可以在ASP.NET MVC中創建兩種類型的Helper方法 :
現在,假設我使用ViewBag
對象將數據從控制器傳遞到視圖。 像那樣:
ViewBag.Fruits = new string[] {"Apple", "Orange", "Pear"};
我在視圖中定義了這樣的內聯輔助方法 :
@helper ListArrayItemsInline(string[] items)
{
...
}
這是一個外部輔助方法 ,它將字符串數組作為輸入:
public static MvcHtmlString ListArrayItemsExternal(this HtmlHelper html, string[] list)
{
...
}
不同的是,如果我想使用外部的,我必須將ViewBag.Fruits
為string[]
。 是的,一切都在這里。 但是,內聯的情況並非如此。 正如我所見,它在運行時評估類型。
// external one, we must cast
@Html.ListArrayItemsExternal((string[])ViewBag.Fruits)
// internal one, works just fine
@ListArrayItemsInline(ViewBag.Fruits)
能否請您解釋一下,如何以及為什么內聯輔助方法在運行時評估類型?
ViewBag
屬性提供了一種將數據傳遞給ViewBag
的靈活方式ViewBag
屬性定義為動態類型 。
public dynamic ViewBag{get;}
當.NET編譯器遇到動態類型時,它會發出一個特殊的代碼塊,而不是簡單地計算表達式。這種特殊的代碼塊將表達式傳遞給動態語言運行時(DLR)以進行運行時評估。
換句話說,任何基於動態類型的表達式都是在運行時編譯的。任何成員設置或從ViewBag中讀出的成員總是被編譯器接受,但在執行之前不會實際評估。
區別僅在於您用於調用幫助程序的語法 : ListArrayItemsInline
是一種常規方法,但ListArrayItemsExternal
是一種擴展方法。 如果您嘗試在不轉換參數的情況下調用ListArrayItemsExternal
作為擴展方法,則編譯器會向您顯示以下錯誤消息:
CS1973:'System.Web.Mvc.HtmlHelper'沒有名為'ListArrayItemsExternal'的適用方法,但似乎有一個名稱的擴展方法。 無法動態分派擴展方法。 考慮轉換動態參數或調用擴展方法而不使用擴展方法語法。
錯誤消息提示了解決錯誤的兩個選項:
選項1.轉換動態參數:
@Html.ListArrayItemsExternal((string[])ViewBag.Fruits)
選項2.使用常規方法語法調用ListArrayItemsExternal
,在這種情況下,您不必轉換動態參數:
MyHelpers.ListArrayItemsExternal(Html, ViewBag.Fruits)
第二個選項演示了可以在運行時為外部幫助程序方法解析類型。 您只需使用正確的語法。
至於為何無法動態調度擴展方法,請查看Eric Lippert的回答 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.