我注意到RazorEngine.Compile()似乎以不同於其他類型的方式處理匿名類型。例如,請考慮下面的代碼:爲什麼RazorEngine動態地使用匿名類型模型編譯模板?
public static void Main()
{
try {
var model = new { s = default(string) };
RazorEngine.Razor.Compile("@Model.s.Length", model.GetType(), "a");
RazorEngine.Razor.Run(model, "a");
} catch (Exception ex) {
Console.WriteLine(ex); // RuntimeBinderException (Cannot perform runtime binding on a null reference)
}
try
{
var model = "";
RazorEngine.Razor.Compile(@"@Model.Length", model.GetType(), "b");
RazorEngine.Razor.Run(default(string), "b");
} catch (Exception ex) {
Console.WriteLine(ex); // NullReferenceException
}
try
{
var model = Tuple.Create(default(string));
RazorEngine.Razor.Compile(@"@Model.Item1.Length", model.GetType(), "c");
RazorEngine.Razor.Run(model, "c");
} catch (Exception ex) {
Console.WriteLine(ex); // NullReferenceException
}
try
{
var model = new Internal();
RazorEngine.Razor.Compile(@"@Model.S.Length", model.GetType(), "d");
RazorEngine.Razor.Run(model, "d");
} catch (Exception ex) {
Console.WriteLine(ex); // TemplateCompilationException (type Internal is not visible)
}
}
internal class Internal {
public string S { get; set; }
}
我的理解是這樣的:匿名類型是內部的,因此通常剃鬚刀不會處理它們。但是,Razor通過生成動態模板來爲匿名類型提供特殊支持。
因此我有兩個問題: (1)我對此行爲的理解是否正確? (2)有沒有辦法讓剃刀爲匿名模型輸出強類型的模板?
如果不太瞭解剃刀是如何工作的,它似乎很可能。雖然匿名類型確實是常規的「強」類型,但在編譯模板時,即使他們想要做這種類型的voodoo,也不可能引用具有確定性的類型(因爲模板可能會被許多控制器調用)。 – millimoose 2013-02-14 16:12:16
但是,假設它們生成了一個類,它們可以爲具有相同模式的本地匿名類型生成代碼,並從一個類型映射到另一個類型。 – ChaseMedallion 2013-02-14 16:15:40
他們可以做所有的事情,但當它們的價值超過所需的努力時,它們中的大多數可以很容易地踢。在這種情況下,除了爲了強類型而強制鍵入代碼之外,沒有什麼好處。 – millimoose 2013-02-14 16:20:43