【问题标题】:How is this generic function working?这个通用函数是如何工作的?
【发布时间】:2015-04-24 08:48:16
【问题描述】:

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

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 属性的简单委托。那么这个东西是如何工作的呢?

【问题讨论】:

    标签: vb.net linq generics


    【解决方案1】:

    Expression(Of T) 是编译器知道的一种特殊类型,这就是神奇之处。

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

    它主要对查询提供者有用,例如Entity Framework 使用它来生成可以针对数据库运行的适当 SQL 代码。

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

    【讨论】:

    • ... Expression(Of T) 是编译器知道的一种特殊类型,这就是它的魔力所在 ...谢谢。
    猜你喜欢
    • 1970-01-01
    • 2018-07-17
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-29
    相关资源
    最近更新 更多