vb.net - 这个通用函数是如何工作的?

标签 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是一个字符串类型的属性。另外,ExpressionLinq命名空间。所以参数必须是一个 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/

相关文章:

sql-server - 在 LINQ 查询中使用 DateTime?.Value.TimeOfDay

LINQ:Group By + Where in 子句

css - Attributes.Add ("class", "className") 但保留现有类

c# - 我可以一次合并这两个列表吗

xml - 尝试使用 VB.net 序列化和反序列化复杂的 xml 文件

java - 为什么 netty Promise 监听器签名 future 的返回类型是 <?超V>

c# - 非泛型 IEnumerable 和泛型 IEnumerable<T> 之间有什么区别?

Java 泛型 : instantiating A with a single constructor argument B

sql - 选择今天日期的电话

使用 VB.NET 调用带有字符指针的非托管 C DLL