是否有人在数据绑定表达式中成功使用了扩展方法?
假设我有一个名为“GetName”的扩展方法附加到“MyClass”。
在后面的代码中,我已经验证了这一点:
MyClass myObject = new MyClass();
MyClass.GetName();
但是,在Web表单中,我试试这个:
<%@ Import Namespace="My.Namespace" %>
然后,在Repeater的ItemTemplate中:
<%# ((MyClass)Container.DataItem).GetName() %>
Visual Studio很酷,Intellisense同意一切,项目构建。但是当我运行它时,我得到了:
编译错误
'My.Namespace.MyClass'不包含'GetName'的定义
因此,代码隐藏将接受扩展方法,但不接受Web表单。我怀疑这是一个名称间距问题,但我在两个地方都导入了相同的命名空间。
答案 0 :(得分:3)
aspx / ascx文件中的数据绑定语法非常挑剔。存在一定量的解析,特别是在该绑定区域中。看看这个例子:
这有效:
<%# String.Format("{0:C}", DataBinder.Eval("Foo")) %>
但这不是:
<%# String.Format("{0:C}", Bind("Foo")) %>
为什么呢?因为虽然DataBinder.Eval是一个真正的方法,但Bind却不是。是的,实际上,它只是表达式binder / parser识别的一个令牌 - 它实际上并没有被编译。我认为DataBinder.Eval可能是特殊的,因为它与ASP.NET 1.1 / 1.0的兼容性。
为了完成这个例子,绑定上述表达式的正确方法是使用:
<%# Bind("Foo", "{0:C}") %>
希望这有帮助,
澄清编辑: C#编译器了解扩展方法。 asp.net表达式解析器没有。
答案 1 :(得分:3)
如果您要绑定到集合并希望利用强类型类MyClass,则可以在代码隐藏中的函数中执行扩展。
您的转发器可以使用
<%# GetObjectName((MyClass)Container.DataItem) %>
您的CodeBehind将具有:
protected string GetObjectName(MyClass obJect)
{
return obJect.GetName();
}
不要忘记导入扩展模块的命名空间。