有问题的功能称为模板化的Razor委托或内联Razor模板,它们可以生成Func(或VB.NET中的Func(Of T,TResult),另请参见What is Func, how and when is it used),并允许使用@< tag>插入代码段. < / tag>格式.
创建模板化的Razor委托的常用方法使用如下语法:
C#
@{
string myString = "mystring";
Func helper = @@myString;
}
@String.Format("{0}", helper(myString))
VB.NET
@Code
Dim myString As String = "mystring"
Dim helper = (@@@myString)
@End Code
@String.Format("{0}", helper(myString))
VB.NET定义实际上具有这样的lambda表达式(通过应用GetType()方法,我们可以知道lambda背后的基础类型):
Dim helper = Function(o As Object)
@@myString
End Function
C#和VB.NET委托实现之间的区别是,VB.NET默认使用relaxed delegate conversion,它能够为非相同参数的委托(甚至是匿名委托)分配函数(包括lambda)给委托,但仅当Option Strict设置打开时才可用关.如果您在Razor视图上使用上述表达式添加@Option Strict On,您将看到此错误:
Option Strict On requires each lambda expression parameter to be
declared with an ‘As’ clause if its type cannot be inferred.
简而言之,您不能在Option Strict On上使用匿名委托,而只能使用Func(Of Object,HelperResult).
该功能在C#中不存在,C#是Func< T,TResult>的显式转换.必须用于从具有TResult类型的lambda创建实例:
var result = (Func)(@@myString);
如果您使用var result =(@< text> @ myString< / text>));直接发生此异常是因为编译器不知道是否应将其转换为委托:
Cannot assign lambda expression to an implicitly-typed local variable
因此,相同的规则也适用于String.Format()方法,该方法包含对象作为第二个参数:
// Error: cannot convert lambda expression to type 'object' because it is not a delegate type
@String.Format("{0}", ((@@myString)))
@String.Format("{0}", ((@@myString))(null))
// Correct
@String.Format("{0}", ((Func)(@@myString)))
@String.Format("{0}", ((Func)(@@myString))(null))
关于Kendo帮助程序问题,Kendo UI WindowBuilder内部的Content()方法重载之一包含Func< object,object>.委托类型作为参数:
namespace Kendo.Mvc.UI.Fluent
{
public class WindowBuilder : WidgetBuilderBase, IHideObjectMembers
{
// other methods
public WindowBuilder Content(Func value)
{
base.Component.Template.InlineTemplate = value; // this is the inline template
return this;
}
// other methods
}
}
其中InlineTemplate属性声明为Func< T,object> ;:
public Func InlineTemplate
{
get
{
return this.inlineTemplate;
}
set
{
this.inlineTemplate = value;
this.binder = delegate(T dataItem, IHtmlNode node)
{
// skipped for brevity
};
}
}
因此,您可以在CSHTML页面中将lambda表达式作为参数传递:
@(Html.Kendo().Window()
.Name("SomeWindow")
.Draggable()
.Modal(true)
.Title("")
.Width(300)
.Content(@SomeValue : @LocalizedResources.SomeValue))
笔记:
1)VB $AnonymousDelegate和Func(Of T,TResult)不是同一类型.
2)任何接受模板化Razor委托的助手都必须将TResult参数定义为HelperResult,因此带有内联模板的@@引用Func(Of T,HelperResult).
参考: