1

在 vb.net 中,这是可序列化的:

 <Serializable()>
Class FunctionHolder
    Private _F As Func(Of Double, Double)
    Sub New()
        Me._F = Function(d As Double) d * 5#
    End Sub
End Class

而对于此序列化失败:

 <Serializable()>
Class FunctionHolder
    Private _F As Func(Of Double, Double)
    Sub New()
        Dim c = 5#
        Me._F = Function(d As Double) d * c
    End Sub
End Class

大概是因为引用本地 varc意味着 lambda 表达式现在有一个闭包。我对此的了解是粗略的,所以如果这是错误的,请纠正我。

所以我在想,如果你想让 lambda 表达式可序列化,最好只给它们原始文字。但是我的代码使得在创建 lambda 时很难完全避免变量。有什么方法可以在 lambda 表达式中使用本地原始变量,但是为了序列化的目的,以某种方式让表达式将其“视为”简单的文字值?

4

2 回答 2

1

通常 lambda 表达式被编译为与定义它们的函数相同的类中的函数。但是,如果 lambda 表达式访问周围函数的局部变量,则需要以某种方式使其可用。

编译器通过在围绕 lambda 表达式的函数类中创建嵌套类型来解决该问题。该类型包含 lambda 表达式函数和 lambda 表达式使用的任何局部变量的实例变量。

换句话说,为了调用访问周围局部变量的 lambda 表达式,您实际上创建了一个包含这些变量副本的对象。如果你想防止这种情况(这也可能防止你的序列化问题),你必须将值作为参数传递给 lambda 表达式。

编辑:自动生成的嵌套类型可能不可序列化,但需要序列化委托。

于 2012-05-17T18:49:52.443 回答
1

对于这个大概简化的示例,使用 VB10 的多语句 lambda,您可以在c每次调用函数时重新计算:

<Serializable()>
Class FunctionHolder
    Private _F As Func(Of Double, Double)
    Sub New()
        Me._F = Function(d As Double)
                  Dim c = 5#
                  Return d * c
                End Function
    End Sub
End Class

(未经测试)

于 2012-11-14T15:09:19.703 回答