这个通用函数如何工作?

时间:2015-04-24 08:48:17

标签: vb.net linq generics

当我看到表格的函数调用时:

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是String类型属性。此外,Expression位于Linq命名空间中。所以论证必须是一个linq表达式。但是,Function() Name不是Linq!它是Name财产的普通代表。那这件事怎么样?

1 个答案:

答案 0 :(得分:2)

Expression(Of T)是编译器所知道的特殊类型,也就是神奇的地方。

当您将lambda表达式(如提到的Function() Name)分配给委托类型(例如Func(Of String))时,编译器将生成可执行代码,但是当您将相同的lambda表达式分配给{{1}时它将生成一个Expression Tree,它是一个代表你的代码的树结构。

它主要用于查询提供程序,例如实体框架使用它来生成可以针对数据库运行的正确SQL代码。

您可以通过调用Expression(Of Func(Of String))方法在运行时将Expression(Of Func(Of String))转换为Func(Of String)。据我所知,将Compile转换为Func(Of String)是不可能的。您可以使用Expression(Of Func(String))类方法手动创建树,但没有任何东西可以通过将委托传递给它来自动生成。