4

バイナリシリアル化を使用して、C#クラスからF#レコードを保存しました。すべて正常に動作します:

F#:

type GameState =
    {
        LevelStatus : LevelStatus
        Grid : Variable<Option<Ball> [,]>
        ...
    }
let game_state : GameState = aGameState()

C#:

public void OnSaveGame() {
    using (var stream = File.Open("game_status.sav", FileMode.Create))
    {
        var binary_formatter = new BinaryFormatter();
        binary_formatter.Serialize(stream, PuzzleBobble.game_state);
    }
}

現在、F#モジュールをリファクタリングしており、シリアル化するための可変レコードが必要です。

let mutable game_state = aGameState()
game_state <- myGameState()

この方法でファイルが作成されますが、逆シリアル化しようとするとnullオブジェクトが返されます。
追加された可変キーワードを除いて、以前の実装は何も変更していません。

私の質問は、可変F#レコードのシリアル化に何か問題がありますか?または、シリアル化自体は正しいので、コードのどこかで別のエラーを探す必要がありますか?

編集:

提案された@Brianのような方法でレコードにアクセスしても、機能しないようです。

詳細は次のとおりです。以前に保存したオブジェクトをこの方法で逆シリアル化すると(game_stateが可変であると宣言されていなくても機能します):

public void OnLoadGame() {
        using (var stream = File.Open("game_status.sav", FileMode.Open))
        {
            var binary_formatter = new BinaryFormatter();
            try
            {
                GameLogic.GameState state = binary_formatter.Deserialize(stream) as GameLogic.GameState;
                GameLogic.load_game_state(state);
            }
            catch (ArgumentNullException e) {
                Console.WriteLine(e.Message);  
            }       


        }
    }

次の例外が発生します。

FSharp.Core.dllの「System.ArgumentNullException」

4

1 に答える 1

1

F# ライブラリのモジュール スコープの変更可能な変数が適切に初期化されないという奇妙なバグを見たことがあります。

定義するコードを変更した場合

let getGameState() = game_state
let setGameState(x) = game_state <- x

次に、変更可能な変数を直接参照する代わりに、get/set 関数を使用すると、問題は解決しますか? もしそうなら、これは私たちが知っているエキゾチックなコンパイラのバグである可能性があります.

于 2011-12-19T23:56:56.213 に答える