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

おそらく、ローカル変数を参照するcということは、ラムダ式がクロージャを持つことを意味するためです。これについての私の知識は大雑把なので、それが間違っている場合は訂正してください。

したがって、ラムダ式をシリアル化できるようにする場合は、プリミティブリテラルのみを指定するのが最善だと思います。しかし、私のコードでは、ラムダを作成するときに変数を完全に回避することは非常に困難です。ラムダ式でローカルプリミティブ変数を使用する方法はありますが、シリアル化の目的で、式を単にリテラル値として「処理」する方法はありますか?

4

2 に答える 2

1

通常、ラムダ式は、それらを定義する関数と同じクラス内の関数としてコンパイルされます。ただし、ラムダ式が周囲の関数のローカル変数にアクセスする場合、何らかの方法でそれらを使用できるようにする必要があります。

コンパイラは、ラムダ式を囲む関数のクラスにネストされた型を作成することで、この問題を解決します。その型には、ラムダ式関数と、ラムダ式が使用するすべてのローカル変数のインスタンス変数が含まれています。

つまり、周囲のローカル変数にアクセスするラムダ式を呼び出すには、それらの変数のコピーを保持するオブジェクトを実際に作成します。それを防ぎたい場合 (また、シリアライゼーションの問題も防ぐ可能性がある場合)、値をパラメータとしてラムダ式に渡す必要があります。

編集:自動生成されたネストされた型はおそらくシリアル化できませんが、デリゲートをシリアル化する必要があります。

于 2012-05-17T18:49:52.443 に答える
1

このおそらく簡略化された例では、VB10 のマルチステートメント ラムダを使用し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 に答える