当我看到以下形式的函数调用时:
Dim i as Integer = getAnInteger("I am groot")
我可以弄清楚
getAnInteger
的签名应该是这样的Function getAnInteger(inp As String) As Integer
现在,我有这个电话:
Property Name As String
Get
Return _name
End Get
Set(ByVal value as String)
_name = value
doSomething(Function() Name) '<---- this one
End Set
End Property
我发现
doSomething
必须像这样定义Sub doSomething(ByVal fnName As Func(Of String))
'
' or
'
Sub doSomething(Of T)(ByVal fnName As Func(Of T)) '....................(1)
我发现它是
Sub doSomething(Of T)(ByVal fnName As Expression(Of Func(Of T))) '.....(2)
问题
怎么两个
Func(Of T)
和 Expression(Of Func(Of T))
可以接受参数Function() Name
在哪里 Name
是一个字符串类型的属性。另外,Expression
在 Linq
命名空间。所以参数必须是一个 linq 表达式。但是,Function() Name
不是Linq!它是 Name
的普通委托(delegate)属性(property)。那么这个东西是如何工作的呢?
最佳答案
Expression(Of T)
是编译器知道的一种特殊类型,这就是神奇之处。
当您将 lambda 表达式(如提到的 Function() Name
)分配给委托(delegate)类型(例如 Func(Of String)
)时,编译器将生成可执行代码,但是当您将相同的 lambda 表达式分配给 Expression(Of Func(Of String))
时它将生成 Expression Tree ,这是一个代表您的代码的树结构。
它主要对查询提供者有用,例如Entity Framework 使用它来生成可以针对数据库运行的适当 SQL 代码。
您可以转换Expression(Of Func(Of String))
至Func(Of String)
在运行时调用 Compile
方法。转换 Func(Of String)
至Expression(Of Func(String))
据我所知,这是不可能的。您可以使用 Expression
手动创建树。类方法,但没有什么可以通过将委托(delegate)传递给它来自动发生。
关于vb.net - 这个通用函数是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29842778/